]> granicus.if.org Git - gc/commitdiff
gc6.2 tarball import gc6_2
authorIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 13:28:12 +0000 (17:28 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 13:28:12 +0000 (17:28 +0400)
71 files changed:
AmigaOS.c [changed mode: 0755->0644]
BCC_MAKEFILE
Makefile
Makefile.am
Makefile.direct
Makefile.dj
Makefile.in
acinclude.m4
aclocal.m4
aix_irix_threads.c [moved from irix_threads.c with 70% similarity]
alloc.c
backgraph.c
configure
configure.host
configure.in
cord/cordbscs.c
cord/de_win.c
darwin_stop_world.c [new file with mode: 0644]
dbg_mlc.c
digimars.mak [changed mode: 0755->0644]
doc/Makefile.am [new file with mode: 0644]
doc/Makefile.in [new file with mode: 0644]
doc/README
doc/README.MacOSX
doc/README.changes
doc/README.darwin [new file with mode: 0644]
doc/README.macros
doc/README.win32
doc/gcdescr.html
doc/gcinterface.html [new file with mode: 0644]
doc/scale.html [new file with mode: 0644]
doc/tree.html
dyn_load.c
finalize.c
gc_dlopen.c
if_mach.c
include/Makefile.am [new file with mode: 0644]
include/Makefile.in [new file with mode: 0644]
include/gc.h
include/gc_config_macros.h [new file with mode: 0644]
include/gc_cpp.h
include/gc_mark.h
include/gc_pthread_redirects.h
include/gc_typed.h
include/private/darwin_semaphore.h [new file with mode: 0644]
include/private/darwin_stop_world.h [new file with mode: 0644]
include/private/gc_locks.h
include/private/gc_pmark.h
include/private/gc_priv.h
include/private/gcconfig.h
include/private/pthread_stop_world.h [new file with mode: 0644]
include/private/pthread_support.h [new file with mode: 0644]
include/private/specific.h
mach_dep.c
mark.c
mark_rts.c
mips_sgi_mach_dep.s [moved from mips_sgi_mach_dep.S with 74% similarity]
misc.c
os_dep.c
powerpc_darwin_mach_dep.s [new file with mode: 0644]
powerpc_macosx_mach_dep.s [deleted file]
pthread_stop_world.c [new file with mode: 0644]
pthread_support.c [moved from linux_threads.c with 71% similarity]
ptr_chck.c
reclaim.c
tests/test.c
tests/test_cpp.cc
threadlibs.c
typd_mlc.c
version.h
win32_threads.c

old mode 100755 (executable)
new mode 100644 (file)
index 54b860bc567eab4e779761b51a73d68877f363e9..3f86ed56fc4fa2308d5c90a838f8533ae0af8ace 100644 (file)
@@ -6,16 +6,17 @@ bcbin=           $(bc)\bin
 bclib=    $(bc)\lib\r
 bcinclude= $(bc)\include\r
 \r
-gcinclude= $(bc)\gc6.0\include\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)\tlink32\r
-cflags=  -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude);cord -L$(bclib) \\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 -DNO_DEBUGGING -DNO_GETENV -DJAVA_FINALIZATION\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
@@ -53,7 +54,7 @@ gctest.exe: tests\test.obj gc.lib
        $(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
@@ -72,7 +73,7 @@ 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
 |\r
index 17e257bef21083951611a549129af3b4700c32b7..52b9137a922e772c8c659ac5f5718a812eba19b6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -73,8 +73,13 @@ HOSTCFLAGS=$(CFLAGS)
 # -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
@@ -218,6 +223,9 @@ HOSTCFLAGS=$(CFLAGS)
 # -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style
 #   prefetch instructions.  Same restrictions as USE_I686_PREFETCH.
 #   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
@@ -247,8 +255,23 @@ HOSTCFLAGS=$(CFLAGS)
 #   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 linux_threads.c.
+#   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) 
@@ -256,15 +279,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 \
@@ -277,10 +300,12 @@ 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 include/gc_amiga_redirects.h \
     include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \
-    $(CORD_SRCS)
+    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 \
@@ -290,7 +315,8 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
         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.DGUX386 doc/README.arm.cross doc/leak.html
+       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
@@ -298,6 +324,8 @@ TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
 GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \
                 libtool.m4 install-sh configure.host Makefile.in \
                 ltconfig aclocal.m4 config.sub config.guess \
+                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 \
@@ -310,7 +338,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)
 
@@ -355,16 +383,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
 
@@ -459,17 +487,17 @@ 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 \
+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 \
+            $(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 POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
+       ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_darwin_mach_dep.s
        ./if_mach ALPHA LINUX $(CC) -c -o mach_dep.o $(srcdir)/alpha_mach_dep.S
        ./if_mach SPARC SUNOS5 $(CC) -c -o mach_dep.o $(srcdir)/sparc_mach_dep.S
        ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
@@ -517,7 +545,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`
@@ -536,7 +564,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 d99ea33fef60e8538240fcc89f03bbb1826026ed..9c4abfbb8be78d107065b5aa21e94999766e61ff 100644 (file)
 #
 # Original author: Tom Tromey
 # Severely truncated by Hans-J. Boehm
+# Modified by: Grzegorz Jakacki <jakacki at acm dot org>
 
 ## Process this file with automake to produce Makefile.in.
 
-## FIXME: `make dist' in this directory will not currently work.  Many
-## files that should be in the distribution are not mentioned in this
-## Makefile.am.
+## FIXME: `make distcheck' in this directory will not currently work.
+##     This is most likely to the explicit flags passed to submakes.
 
 AUTOMAKE_OPTIONS = foreign
 
-lib_LTLIBRARIES = libgc.la
+SUBDIRS = doc include
+
+EXTRA_DIST = 
+    ## more items will be succesively added below
+
+if CPLUSPLUS
+extra = libgccpp.la
+else
+extra = 
+endif
+lib_LTLIBRARIES = libgc.la $(extra) 
+
+include_HEADERS = include/gc.h include/gc_local_alloc.h \
+include/gc_pthread_redirects.h include/gc_config_macros.h \
+include/leak_detector.h include/gc_typed.h @addincludes@
+
+EXTRA_HEADERS = include/gc_cpp.h include/gc_allocator.h
+
+if POWERPC_DARWIN
+asm_libgc_sources = powerpc_darwin_mach_dep.s
+else
+asm_libgc_sources = 
+endif
 
 libgc_la_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)
 
 # Include THREADLIBS here to ensure that the correct versions of
 # linuxthread semaphore functions get linked:
 libgc_la_LIBADD = @addobjs@ $(THREADLIBS)
 libgc_la_DEPENDENCIES = @addobjs@
-libgc_la_LDFLAGS = -version-info 1:1:0
+libgc_la_LDFLAGS = -version-info 1:2:0
 
 EXTRA_libgc_la_SOURCES = alpha_mach_dep.S \
-mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_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
+    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
+
+libgccpp_la_SOURCES = gc_cpp.cc
+libgccpp_la_LIBADD = $(THREADLIBS)
+libgccpp_la_LDFLAGS = -version-info 1:2:0
+
+EXTRA_DIST += alpha_mach_dep.S mips_sgi_mach_dep.s sparc_mach_dep.S
 
 AM_CXXFLAGS = @GC_CFLAGS@
 AM_CFLAGS = @GC_CFLAGS@
 
-check_PROGRAMS = gctest
-# The following hack produces a warning from automake, but we need it in order 
-# to build a file from a subdirectory. FIXME.
+if CPLUSPLUS
+extra_checks = test_cpp
+else
+extra_checks = 
+endif
+
+check_PROGRAMS = gctest $(extra_checks)
+
 test.o:        $(srcdir)/tests/test.c
        $(COMPILE) -c $(srcdir)/tests/test.c
 #      Using $< in the above seems to fail with the HP/UX on Itanium make.
+test_cpp.o:    $(srcdir)/tests/test_cpp.cc
+       $(COMPILE) -c $(srcdir)/tests/test_cpp.cc
 
+## FIXME: this is probably the reason why some files from BUILT_SOURCES
+##     are included in the distribution
 # gctest_OBJECTS = test.o
-gctest_SOURCES = 
-gctest_LDADD = test.o ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
-TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
-TESTS = gctest
+gctest_SOURCES = tests/test.c
+gctest_LDADD = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
+test_cpp_SOURCES = tests/test_cpp.cc
+test_cpp_LDADD = ./libgc.la ./libgccpp.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
+
+TESTS = gctest $(extra_checks)
 
 ## FIXME: relies on internal code generated by automake.
 all_objs = @addobjs@ $(libgc_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:
@@ -74,47 +117,69 @@ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \
        $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) 
 LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
 
-# Work around what appears to be a GNU make bug handling MAKEFLAGS
-# values defined in terms of make variables, as is the case for CC and
-# friends when we are called from the top level Makefile.
-AM_MAKEFLAGS = \
-       "AR_FLAGS=$(AR_FLAGS)" \
-       "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
-       "CFLAGS=$(CFLAGS)" \
-       "CXXFLAGS=$(CXXFLAGS)" \
-       "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
-       "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
-       "INSTALL=$(INSTALL)" \
-       "INSTALL_DATA=$(INSTALL_DATA)" \
-       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
-       "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
-       "LDFLAGS=$(LDFLAGS)" \
-       "LIBCFLAGS=$(LIBCFLAGS)" \
-       "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
-       "MAKE=$(MAKE)" \
-       "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
-       "PICFLAG=$(PICFLAG)" \
-       "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
-       "SHELL=$(SHELL)" \
-       "EXPECT=$(EXPECT)" \
-       "RUNTEST=$(RUNTEST)" \
-       "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
-       "exec_prefix=$(exec_prefix)" \
-       "infodir=$(infodir)" \
-       "libdir=$(libdir)" \
-       "prefix=$(prefix)" \
-       "tooldir=$(tooldir)" \
-       "AR=$(AR)" \
-       "AS=$(AS)" \
-       "CC=$(CC)" \
-       "CXX=$(CXX)" \
-       "LD=$(LD)" \
-       "LIBCFLAGS=$(LIBCFLAGS)" \
-       "NM=$(NM)" \
-       "PICFLAG=$(PICFLAG)" \
-       "RANLIB=$(RANLIB)" \
-       "DESTDIR=$(DESTDIR)"
+## We need to add DEFS to assembler flags
+## :FIXME: what if assembler does not accept -D... ?
+##     (use Autoconf to prepare ASDEFS ???)
+
+CCASFLAGS += $(DEFS)
+
+dist_noinst_SCRIPTS = callprocs configure.host
+    ## callprocs --- used by Makefile.{dj,direct}
+    ## configure.host --- used by Makefile.{am,dj,direct}
 
+# headers which are not installed
+# (see include/Makefile.am for more)
+#
+dist_noinst_HEADERS = version.h
+
+# documentation which is not installed
+#
+EXTRA_DIST += README.QUICK
+
+# other makefiles
+# :GOTCHA: deliberately we do not include 'Makefile'
+EXTRA_DIST += BCC_MAKEFILE NT_MAKEFILE NT_THREADS_MAKEFILE \
+    OS2_MAKEFILE PCR-Makefile digimars.mak EMX_MAKEFILE        \
+    Makefile.direct Makefile.dj        Makefile.DLLs SMakefile.amiga \
+    WCC_MAKEFILE
+
+# files used by makefiles other than Makefile.am
+# (:FIXME: do we really need gcc_support.c ?)
+#
+EXTRA_DIST += add_gc_prefix.c gcname.c if_mach.c if_not_there.c \
+    hpux_test_and_clear.s pc_excludes gc.mak MacOS.c \
+    MacProjects.sit.hqx gcc_support.c mach_dep.c setjmp_t.c \
+    threadlibs.c AmigaOS.c \
+    Mac_files/datastart.c Mac_files/dataend.c \
+    Mac_files/MacOS_config.h Mac_files/MacOS_Test_config.h
+
+# part of C++ interface
+#
+EXTRA_DIST += gc_cpp.cc gc_cpp.cpp
+
+# tests not used by Makefile.am (:FIXME: why?)
+#
+EXTRA_DIST += tests/test_cpp.cc tests/trace_test.c \
+    tests/leak_test.c tests/thread_leak_test.c
+
+# cord package
+#
+EXTRA_DIST += cord/cordbscs.c cord/cordtest.c cord/de.c cord/de_win.c \
+    cord/de_win.ICO cord/cordprnt.c cord/cordxtra.c cord/de_cmds.h \
+    cord/de_win.h cord/de_win.RC
+
+# this is an auxiliary shell file used by Makefile and Makefile.direct
+#
 CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host
 
+# :FIXME: why do we distribute this one???
+#
+EXTRA_DIST += libtool.m4
+
 MAKEOVERRIDES=
+
+#
+# :GOTCHA: GNU make rule for making .s out of .S is flawed, 
+# it will not remove dest if building fails
+.S.s:
+       if $(CPP) $< >$@ ; then :; else rm -f $@; fi
index 17e257bef21083951611a549129af3b4700c32b7..52b9137a922e772c8c659ac5f5718a812eba19b6 100644 (file)
@@ -73,8 +73,13 @@ HOSTCFLAGS=$(CFLAGS)
 # -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
@@ -218,6 +223,9 @@ HOSTCFLAGS=$(CFLAGS)
 # -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style
 #   prefetch instructions.  Same restrictions as USE_I686_PREFETCH.
 #   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
@@ -247,8 +255,23 @@ HOSTCFLAGS=$(CFLAGS)
 #   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 linux_threads.c.
+#   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) 
@@ -256,15 +279,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 \
@@ -277,10 +300,12 @@ 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 include/gc_amiga_redirects.h \
     include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \
-    $(CORD_SRCS)
+    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 \
@@ -290,7 +315,8 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
         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.DGUX386 doc/README.arm.cross doc/leak.html
+       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
@@ -298,6 +324,8 @@ TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
 GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \
                 libtool.m4 install-sh configure.host Makefile.in \
                 ltconfig aclocal.m4 config.sub config.guess \
+                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 \
@@ -310,7 +338,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)
 
@@ -355,16 +383,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
 
@@ -459,17 +487,17 @@ 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 \
+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 \
+            $(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 POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
+       ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_darwin_mach_dep.s
        ./if_mach ALPHA LINUX $(CC) -c -o mach_dep.o $(srcdir)/alpha_mach_dep.S
        ./if_mach SPARC SUNOS5 $(CC) -c -o mach_dep.o $(srcdir)/sparc_mach_dep.S
        ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
@@ -517,7 +545,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`
@@ -536,7 +564,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 146c83b9781aef3bb6e8fffa52ed3d919dcd6f09..6097293ff0e7966f21482ce16164b7ce87b88824 100644 (file)
@@ -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 \
@@ -285,13 +285,13 @@ liblinuxgc.so: $(OBJS) dyn_load.o
        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)
+            $(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 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 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
index 0e735384cd2d29123962c962dd7e942142ac2dbb..3def876e70ed8b45497783d6110e011eebe9d71b 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.6.1 from Makefile.am.
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
 # @configure_input@
 
 # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
@@ -27,6 +27,7 @@
 #
 # Original author: Tom Tromey
 # Severely truncated by Hans-J. Boehm
+# Modified by: Grzegorz Jakacki <jakacki at acm dot org>
 SHELL = @SHELL@
 
 srcdir = @srcdir@
@@ -63,6 +64,7 @@ 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@
@@ -84,7 +86,8 @@ AS = @AS@
 AWK = @AWK@
 CC = @CC@
 CCAS = @CCAS@
-CCASFLAGS = @CCASFLAGS@
+
+CCASFLAGS = @CCASFLAGS@ $(DEFS)
 CFLAGS = @CFLAGS@
 CXX = @CXX@
 CXXFLAGS = @CXXFLAGS@
@@ -94,6 +97,7 @@ 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@
@@ -106,48 +110,113 @@ RANLIB = @RANLIB@
 STRIP = @STRIP@
 THREADLIBS = @THREADLIBS@
 VERSION = @VERSION@
+addincludes = @addincludes@
+addlibs = @addlibs@
 addobjs = @addobjs@
+addtests = @addtests@
 am__include = @am__include@
 am__quote = @am__quote@
-gc_basedir = @gc_basedir@
 install_sh = @install_sh@
 target_all = @target_all@
 
 AUTOMAKE_OPTIONS = foreign
 
-lib_LTLIBRARIES = libgc.la
+SUBDIRS = doc include
+
+
+# documentation which is not installed
+#
+
+# other makefiles
+# :GOTCHA: deliberately we do not include 'Makefile'
+
+# files used by makefiles other than Makefile.am
+# (:FIXME: do we really need gcc_support.c ?)
+#
+
+# part of C++ interface
+#
+
+# tests not used by Makefile.am (:FIXME: why?)
+#
+
+# cord package
+#
+
+# :FIXME: why do we distribute this one???
+#
+EXTRA_DIST = alpha_mach_dep.S mips_sgi_mach_dep.s sparc_mach_dep.S README.QUICK BCC_MAKEFILE NT_MAKEFILE NT_THREADS_MAKEFILE \
+    OS2_MAKEFILE PCR-Makefile digimars.mak EMX_MAKEFILE        \
+    Makefile.direct Makefile.dj        Makefile.DLLs SMakefile.amiga \
+    WCC_MAKEFILE\
+add_gc_prefix.c gcname.c if_mach.c if_not_there.c \
+    hpux_test_and_clear.s pc_excludes gc.mak MacOS.c \
+    MacProjects.sit.hqx gcc_support.c mach_dep.c setjmp_t.c \
+    threadlibs.c AmigaOS.c \
+    Mac_files/datastart.c Mac_files/dataend.c \
+    Mac_files/MacOS_config.h Mac_files/MacOS_Test_config.h\
+gc_cpp.cc gc_cpp.cpp tests/test_cpp.cc tests/trace_test.c \
+    tests/leak_test.c tests/thread_leak_test.c\
+cord/cordbscs.c cord/cordtest.c cord/de.c cord/de_win.c \
+    cord/de_win.ICO cord/cordprnt.c cord/cordxtra.c cord/de_cmds.h \
+    cord/de_win.h cord/de_win.RC\
+libtool.m4
+
+@CPLUSPLUS_TRUE@extra = libgccpp.la
+@CPLUSPLUS_FALSE@extra = 
+lib_LTLIBRARIES = libgc.la $(extra) 
+
+include_HEADERS = include/gc.h include/gc_local_alloc.h \
+include/gc_pthread_redirects.h include/gc_config_macros.h \
+include/leak_detector.h include/gc_typed.h @addincludes@
+
+
+EXTRA_HEADERS = include/gc_cpp.h include/gc_allocator.h
+
+@POWERPC_DARWIN_TRUE@asm_libgc_sources = powerpc_darwin_mach_dep.s
+@POWERPC_DARWIN_FALSE@asm_libgc_sources = 
 
 libgc_la_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)
 
 
 # Include THREADLIBS here to ensure that the correct versions of
 # linuxthread semaphore functions get linked:
 libgc_la_LIBADD = @addobjs@ $(THREADLIBS)
 libgc_la_DEPENDENCIES = @addobjs@
-libgc_la_LDFLAGS = -version-info 1:1:0
+libgc_la_LDFLAGS = -version-info 1:2:0
 
 EXTRA_libgc_la_SOURCES = alpha_mach_dep.S \
-mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_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
+    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
 
 
+libgccpp_la_SOURCES = gc_cpp.cc
+libgccpp_la_LIBADD = $(THREADLIBS)
+libgccpp_la_LDFLAGS = -version-info 1:2:0
+
 AM_CXXFLAGS = @GC_CFLAGS@
 AM_CFLAGS = @GC_CFLAGS@
 
-check_PROGRAMS = gctest
-#      Using $< in the above seems to fail with the HP/UX on Itanium make.
+@CPLUSPLUS_TRUE@extra_checks = test_cpp
+@CPLUSPLUS_FALSE@extra_checks = 
+
+check_PROGRAMS = gctest $(extra_checks)
 
 # gctest_OBJECTS = test.o
-gctest_SOURCES = 
-gctest_LDADD = test.o ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
-TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
-TESTS = gctest
+gctest_SOURCES = tests/test.c
+gctest_LDADD = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
+test_cpp_SOURCES = tests/test_cpp.cc
+test_cpp_LDADD = ./libgc.la ./libgccpp.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
+
+TESTS = gctest $(extra_checks)
 
 all_objs = @addobjs@ $(libgc_la_OBJECTS)
 
@@ -157,48 +226,15 @@ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \
 
 LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
 
-# Work around what appears to be a GNU make bug handling MAKEFLAGS
-# values defined in terms of make variables, as is the case for CC and
-# friends when we are called from the top level Makefile.
-AM_MAKEFLAGS = \
-       "AR_FLAGS=$(AR_FLAGS)" \
-       "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
-       "CFLAGS=$(CFLAGS)" \
-       "CXXFLAGS=$(CXXFLAGS)" \
-       "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
-       "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
-       "INSTALL=$(INSTALL)" \
-       "INSTALL_DATA=$(INSTALL_DATA)" \
-       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
-       "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
-       "LDFLAGS=$(LDFLAGS)" \
-       "LIBCFLAGS=$(LIBCFLAGS)" \
-       "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
-       "MAKE=$(MAKE)" \
-       "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
-       "PICFLAG=$(PICFLAG)" \
-       "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
-       "SHELL=$(SHELL)" \
-       "EXPECT=$(EXPECT)" \
-       "RUNTEST=$(RUNTEST)" \
-       "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
-       "exec_prefix=$(exec_prefix)" \
-       "infodir=$(infodir)" \
-       "libdir=$(libdir)" \
-       "prefix=$(prefix)" \
-       "tooldir=$(tooldir)" \
-       "AR=$(AR)" \
-       "AS=$(AS)" \
-       "CC=$(CC)" \
-       "CXX=$(CXX)" \
-       "LD=$(LD)" \
-       "LIBCFLAGS=$(LIBCFLAGS)" \
-       "NM=$(NM)" \
-       "PICFLAG=$(PICFLAG)" \
-       "RANLIB=$(RANLIB)" \
-       "DESTDIR=$(DESTDIR)"
+dist_noinst_SCRIPTS = callprocs configure.host
 
+# headers which are not installed
+# (see include/Makefile.am for more)
+#
+dist_noinst_HEADERS = version.h
 
+# this is an auxiliary shell file used by Makefile and Makefile.direct
+#
 CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host
 
 MAKEOVERRIDES = 
@@ -208,19 +244,32 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_CLEAN_FILES =
 LTLIBRARIES = $(lib_LTLIBRARIES)
 
+@POWERPC_DARWIN_TRUE@am__objects_1 = powerpc_darwin_mach_dep.lo
+@POWERPC_DARWIN_FALSE@am__objects_1 =
 am_libgc_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
+       headers.lo aix_irix_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 pthread_support.lo \
+       pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1)
 libgc_la_OBJECTS = $(am_libgc_la_OBJECTS)
-check_PROGRAMS = gctest$(EXEEXT)
-am_gctest_OBJECTS =
+libgccpp_la_DEPENDENCIES =
+am_libgccpp_la_OBJECTS = gc_cpp.lo
+libgccpp_la_OBJECTS = $(am_libgccpp_la_OBJECTS)
+@CPLUSPLUS_TRUE@check_PROGRAMS = gctest$(EXEEXT) test_cpp$(EXEEXT)
+@CPLUSPLUS_FALSE@check_PROGRAMS = gctest$(EXEEXT)
+am_gctest_OBJECTS = test.$(OBJEXT)
 gctest_OBJECTS = $(am_gctest_OBJECTS)
-gctest_DEPENDENCIES = test.o ./libgc.la
+gctest_DEPENDENCIES = ./libgc.la
 gctest_LDFLAGS =
+am_test_cpp_OBJECTS = test_cpp.$(OBJEXT)
+test_cpp_OBJECTS = $(am_test_cpp_OBJECTS)
+test_cpp_DEPENDENCIES = ./libgc.la ./libgccpp.la
+test_cpp_LDFLAGS =
+SCRIPTS = $(dist_noinst_SCRIPTS)
+
 
 DEFS = @DEFS@
 DEFAULT_INCLUDES =  -I. -I$(srcdir)
@@ -229,24 +278,28 @@ LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/allchblk.Plo ./$(DEPDIR)/alloc.Plo \
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/aix_irix_threads.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/allchblk.Plo ./$(DEPDIR)/alloc.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/backgraph.Plo ./$(DEPDIR)/blacklst.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/checksums.Plo ./$(DEPDIR)/dbg_mlc.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/dyn_load.Plo ./$(DEPDIR)/finalize.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/checksums.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/darwin_stop_world.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/dbg_mlc.Plo ./$(DEPDIR)/dyn_load.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/finalize.Plo ./$(DEPDIR)/gc_cpp.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/gc_dlopen.Plo ./$(DEPDIR)/gcj_mlc.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/headers.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/irix_threads.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/linux_threads.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/malloc.Plo ./$(DEPDIR)/mallocx.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/mark.Plo ./$(DEPDIR)/mark_rts.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/misc.Plo ./$(DEPDIR)/new_hblk.Plo \
-@AMDEP_TRUE@   ./$(DEPDIR)/obj_map.Plo ./$(DEPDIR)/os_dep.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/headers.Plo ./$(DEPDIR)/malloc.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/mallocx.Plo ./$(DEPDIR)/mark.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/mark_rts.Plo ./$(DEPDIR)/misc.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/new_hblk.Plo ./$(DEPDIR)/obj_map.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/os_dep.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/pcr_interface.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/pthread_stop_world.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/pthread_support.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/ptr_chck.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/real_malloc.Plo ./$(DEPDIR)/reclaim.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/solaris_pthreads.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/solaris_threads.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/specific.Plo ./$(DEPDIR)/stubborn.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/test.Po ./$(DEPDIR)/test_cpp.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/typd_mlc.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/win32_threads.Plo
 CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
@@ -255,17 +308,37 @@ LTCCASCOMPILE = $(LIBTOOL) --mode=compile $(CCAS) $(AM_CCASFLAGS) \
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
 DIST_SOURCES = $(libgc_la_SOURCES) $(EXTRA_libgc_la_SOURCES) \
-       $(gctest_SOURCES)
-DIST_COMMON = Makefile.am Makefile.in acinclude.m4 aclocal.m4 \
-       config.guess config.sub configure configure.in depcomp \
-       install-sh ltconfig ltmain.sh missing mkinstalldirs
-SOURCES = $(libgc_la_SOURCES) $(EXTRA_libgc_la_SOURCES) $(gctest_SOURCES)
+       $(libgccpp_la_SOURCES) $(gctest_SOURCES) $(test_cpp_SOURCES)
+HEADERS = $(dist_noinst_HEADERS) $(include_HEADERS)
+
 
-all: all-am
+RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
+       uninstall-info-recursive all-recursive install-data-recursive \
+       install-exec-recursive installdirs-recursive install-recursive \
+       uninstall-recursive check-recursive installcheck-recursive
+DIST_COMMON = $(dist_noinst_HEADERS) $(dist_noinst_SCRIPTS) \
+       $(include_HEADERS) Makefile.am Makefile.in acinclude.m4 \
+       aclocal.m4 config.guess config.sub configure configure.in \
+       depcomp install-sh ltconfig ltmain.sh missing mkinstalldirs
+DIST_SUBDIRS = $(SUBDIRS)
+SOURCES = $(libgc_la_SOURCES) $(EXTRA_libgc_la_SOURCES) $(libgccpp_la_SOURCES) $(gctest_SOURCES) $(test_cpp_SOURCES)
+
+all: all-recursive
 
 .SUFFIXES:
-.SUFFIXES: .S .c .lo .o .obj .s
+.SUFFIXES: .S .c .cc .lo .o .obj .s
+
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
        cd $(top_srcdir) && \
          $(AUTOMAKE) --foreign  Makefile
@@ -301,14 +374,31 @@ uninstall-libLTLIBRARIES:
 
 clean-libLTLIBRARIES:
        -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test -z "$dir" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
 libgc.la: $(libgc_la_OBJECTS) $(libgc_la_DEPENDENCIES) 
        $(LINK) -rpath $(libdir) $(libgc_la_LDFLAGS) $(libgc_la_OBJECTS) $(libgc_la_LIBADD) $(LIBS)
+libgccpp.la: $(libgccpp_la_OBJECTS) $(libgccpp_la_DEPENDENCIES) 
+       $(CXXLINK) -rpath $(libdir) $(libgccpp_la_LDFLAGS) $(libgccpp_la_OBJECTS) $(libgccpp_la_LIBADD) $(LIBS)
 
 clean-checkPROGRAMS:
-       -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+       @list='$(check_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+test.$(OBJEXT): tests/test.c
 gctest$(EXEEXT): $(gctest_OBJECTS) $(gctest_DEPENDENCIES) 
        @rm -f gctest$(EXEEXT)
        $(LINK) $(gctest_LDFLAGS) $(gctest_OBJECTS) $(gctest_LDADD) $(LIBS)
+test_cpp.$(OBJEXT): tests/test_cpp.cc
+test_cpp$(EXEEXT): $(test_cpp_OBJECTS) $(test_cpp_DEPENDENCIES) 
+       @rm -f test_cpp$(EXEEXT)
+       $(CXXLINK) $(test_cpp_LDFLAGS) $(test_cpp_OBJECTS) $(test_cpp_LDADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT) core *.core
@@ -316,19 +406,20 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aix_irix_threads.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allchblk.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backgraph.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blacklst.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checksums.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/darwin_stop_world.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbg_mlc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyn_load.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/finalize.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_cpp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_dlopen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcj_mlc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/headers.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irix_threads.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux_threads.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mallocx.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mark.Plo@am__quote@
@@ -338,6 +429,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obj_map.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_dep.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr_interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_stop_world.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_support.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptr_chck.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/real_malloc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reclaim.Plo@am__quote@
@@ -345,6 +438,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solaris_threads.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specific.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stubborn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cpp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typd_mlc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32_threads.Plo@am__quote@
 
@@ -377,8 +472,51 @@ distclean-depend:
 @AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
 @AMDEP_TRUE@   $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
        $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+test.obj: tests/test.c
+@AMDEP_TRUE@   source='tests/test.c' object='test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/test.Po' tmpdepfile='$(DEPDIR)/test.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test.obj `cygpath -w tests/test.c`
+
+test.lo: tests/test.c
+@AMDEP_TRUE@   source='tests/test.c' object='test.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/test.Plo' tmpdepfile='$(DEPDIR)/test.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test.lo `test -f 'tests/test.c' || echo '$(srcdir)/'`tests/test.c
 CCDEPMODE = @CCDEPMODE@
 
+.cc.o:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+.cc.obj:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(CXXCOMPILE) -c -o $@ `cygpath -w $<`
+
+.cc.lo:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+test_cpp.obj: tests/test_cpp.cc
+@AMDEP_TRUE@   source='tests/test_cpp.cc' object='test_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/test_cpp.Po' tmpdepfile='$(DEPDIR)/test_cpp.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_cpp.obj `cygpath -w tests/test_cpp.cc`
+
+test_cpp.lo: tests/test_cpp.cc
+@AMDEP_TRUE@   source='tests/test_cpp.cc' object='test_cpp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/test_cpp.Plo' tmpdepfile='$(DEPDIR)/test_cpp.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_cpp.lo `test -f 'tests/test_cpp.cc' || echo '$(srcdir)/'`tests/test_cpp.cc
+CXXDEPMODE = @CXXDEPMODE@
+
 .s.o:
        $(CCASCOMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
 
@@ -394,6 +532,79 @@ clean-libtool:
 distclean-libtool:
        -rm -f libtool
 uninstall-info-am:
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+install-includeHEADERS: $(include_HEADERS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(includedir)
+       @list='$(include_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(includedir)/$$f"; \
+         $(includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(includedir)/$$f; \
+       done
+
+uninstall-includeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(include_HEADERS)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f $(DESTDIR)$(includedir)/$$f"; \
+         rm -f $(DESTDIR)$(includedir)/$$f; \
+       done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
 
 ETAGS = etags
 ETAGSFLAGS =
@@ -409,10 +620,15 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
               END { for (i in files) print i; }'`; \
        mkid -fID $$unique
 
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
        here=`pwd`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
@@ -501,7 +717,8 @@ distcleancheck_listfiles = find . -type f -print
 distdir: $(DISTFILES)
        $(am__remove_distdir)
        mkdir $(distdir)
-       @for file in $(DISTFILES); do \
+       $(mkinstalldirs) $(distdir)/Mac_files $(distdir)/cord $(distdir)/include $(distdir)/tests
+       @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 \
@@ -521,6 +738,19 @@ distdir: $(DISTFILES)
            || exit 1; \
          fi; \
        done
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$(top_distdir)" \
+               distdir=../$(distdir)/$$subdir \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
        -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
          ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
          ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
@@ -576,21 +806,21 @@ distcleancheck: distclean
 check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
        $(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+       $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
 
-installdirs:
-       $(mkinstalldirs) $(DESTDIR)$(libdir)
-
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
 
 install-am: all-am
        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
-installcheck: installcheck-am
+installcheck: installcheck-recursive
 install-strip:
        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
          INSTALL_STRIP_FLAG=-s \
@@ -601,73 +831,93 @@ mostlyclean-generic:
 clean-generic:
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+       -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: clean-recursive
 
 clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool mostlyclean-am
 
-distclean: distclean-am
-       -rm -f config.status config.cache config.log
+distclean: distclean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
 distclean-am: clean-am distclean-compile distclean-depend \
        distclean-generic distclean-libtool distclean-tags
 
-dvi: dvi-am
+dvi: dvi-recursive
 
 dvi-am:
 
-info: info-am
+info: info-recursive
 
 info-am:
 
-install-data-am:
+install-data-am: install-includeHEADERS
 
 install-exec-am: install-libLTLIBRARIES
 
-install-info: install-info-am
+install-info: install-info-recursive
 
 install-man:
 
 installcheck-am:
 
-maintainer-clean: maintainer-clean-am
-
+maintainer-clean: maintainer-clean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf autom4te.cache
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
 
 mostlyclean-am: mostlyclean-compile mostlyclean-generic \
        mostlyclean-libtool
 
-uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
-
-.PHONY: GTAGS all all-am check check-TESTS check-am clean \
-       clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
-       clean-libtool dist dist-all dist-gzip distcheck distclean \
-       distclean-compile distclean-depend distclean-generic \
-       distclean-libtool distclean-tags distcleancheck distdir dvi \
-       dvi-am info info-am install install-am install-data \
-       install-data-am install-exec install-exec-am install-info \
-       install-info-am install-libLTLIBRARIES install-man \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-       tags uninstall uninstall-am uninstall-info-am \
+uninstall-am: uninstall-includeHEADERS uninstall-info-am \
        uninstall-libLTLIBRARIES
 
-# The following hack produces a warning from automake, but we need it in order 
-# to build a file from a subdirectory. FIXME.
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-TESTS check-am \
+       clean clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
+       clean-libtool clean-recursive dist dist-all dist-gzip distcheck \
+       distclean distclean-compile distclean-depend distclean-generic \
+       distclean-libtool distclean-recursive distclean-tags \
+       distcleancheck distdir dvi dvi-am dvi-recursive info info-am \
+       info-recursive install install-am install-data install-data-am \
+       install-data-recursive install-exec install-exec-am \
+       install-exec-recursive install-includeHEADERS install-info \
+       install-info-am install-info-recursive install-libLTLIBRARIES \
+       install-man install-recursive install-strip installcheck \
+       installcheck-am installdirs installdirs-am \
+       installdirs-recursive maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
+       tags tags-recursive uninstall uninstall-am \
+       uninstall-includeHEADERS uninstall-info-am \
+       uninstall-info-recursive uninstall-libLTLIBRARIES \
+       uninstall-recursive
+
+
 test.o:        $(srcdir)/tests/test.c
        $(COMPILE) -c $(srcdir)/tests/test.c
+#      Using $< in the above seems to fail with the HP/UX on Itanium make.
+test_cpp.o:    $(srcdir)/tests/test_cpp.cc
+       $(COMPILE) -c $(srcdir)/tests/test_cpp.cc
 $(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 $<
+
+#
+# :GOTCHA: GNU make rule for making .s out of .S is flawed, 
+# it will not remove dest if building fails
+.S.s:
+       if $(CPP) $< >$@ ; then :; else rm -f $@; fi
 # 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 438451f51b261a27c79be98a652bd0030068dd29..72602a0040b2b8f16176c971e0ba3ac0be110991 100644 (file)
@@ -1 +1,49 @@
+# 
+# 
+# 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>
+
+# GC_SET_VERSION
+# sets and AC_DEFINEs GC_VERSION_MAJOR, GC_VERSION_MINOR and GC_ALPHA_VERSION
+# based on the contents of PACKAGE_VERSION; PACKAGE_VERSION must conform to
+# [0-9]+[.][0-9]+(alpha[0.9]+)? 
+# in lex syntax; if there is no alpha number, GC_ALPHA_VERSION is empty
+#
+AC_DEFUN(GC_SET_VERSION, [
+  AC_MSG_CHECKING(GC version numbers)
+  GC_VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([[0-9]][[0-9]]*\)[[.]].*$/\1/g'`
+  GC_VERSION_MINOR=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]]\([[0-9]][[0-9]]*\).*$/\1/g'`
+  GC_ALPHA_VERSION=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]][[0-9]]*//'`
+
+  case "$GC_ALPHA_VERSION" in
+    alpha*) 
+      GC_ALPHA_VERSION=`echo $GC_ALPHA_VERSION \
+      | sed 's/alpha\([[0-9]][[0-9]]*\)/\1/'` ;;
+    *)  GC_ALPHA_MAJOR='' ;;
+  esac
+
+  if test :$GC_VERSION_MAJOR: = :: \
+     -o   :$GC_VERSION_MINOR: = :: ;
+  then
+    AC_MSG_RESULT(invalid)
+    AC_MSG_ERROR([nonconforming PACKAGE_VERSION='$PACKAGE_VERSION'])
+  fi
+  
+  AC_DEFINE_UNQUOTED(GC_VERSION_MAJOR, $GC_VERSION_MAJOR)
+  AC_DEFINE_UNQUOTED(GC_VERSION_MINOR, $GC_VERSION_MINOR)
+  if test :$GC_ALPHA_VERSION: != :: ; then
+    AC_DEFINE_UNQUOTED(GC_ALPHA_VERSION, $GC_ALPHA_VERSION)
+  fi
+  AC_MSG_RESULT(major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \
+${GC_ALPHA_VERSION:+alpha=}$GC_ALPHA_VERSION)
+])
+
 sinclude(libtool.m4)
index 952e4ef12bbdf6388d64c6d1dedf7352905dcad9..ca95db121f0e24ac390186e7a5fa4a49ada73313 100644 (file)
@@ -1,4 +1,4 @@
-# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*-
+# aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*-
 
 # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
 # Free Software Foundation, Inc.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
+# 
+# 
+# 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>
+
+# GC_SET_VERSION
+# sets and AC_DEFINEs GC_VERSION_MAJOR, GC_VERSION_MINOR and GC_ALPHA_VERSION
+# based on the contents of PACKAGE_VERSION; PACKAGE_VERSION must conform to
+# [0-9]+[.][0-9]+(alpha[0.9]+)? 
+# in lex syntax; if there is no alpha number, GC_ALPHA_VERSION is empty
+#
+AC_DEFUN(GC_SET_VERSION, [
+  AC_MSG_CHECKING(GC version numbers)
+  GC_VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([[0-9]][[0-9]]*\)[[.]].*$/\1/g'`
+  GC_VERSION_MINOR=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]]\([[0-9]][[0-9]]*\).*$/\1/g'`
+  GC_ALPHA_VERSION=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]][[0-9]]*//'`
+
+  case "$GC_ALPHA_VERSION" in
+    alpha*) 
+      GC_ALPHA_VERSION=`echo $GC_ALPHA_VERSION \
+      | sed 's/alpha\([[0-9]][[0-9]]*\)/\1/'` ;;
+    *)  GC_ALPHA_MAJOR='' ;;
+  esac
+
+  if test :$GC_VERSION_MAJOR: = :: \
+     -o   :$GC_VERSION_MINOR: = :: ;
+  then
+    AC_MSG_RESULT(invalid)
+    AC_MSG_ERROR([nonconforming PACKAGE_VERSION='$PACKAGE_VERSION'])
+  fi
+  
+  AC_DEFINE_UNQUOTED(GC_VERSION_MAJOR, $GC_VERSION_MAJOR)
+  AC_DEFINE_UNQUOTED(GC_VERSION_MINOR, $GC_VERSION_MINOR)
+  if test :$GC_ALPHA_VERSION: != :: ; then
+    AC_DEFINE_UNQUOTED(GC_ALPHA_VERSION, $GC_ALPHA_VERSION)
+  fi
+  AC_MSG_RESULT(major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \
+${GC_ALPHA_VERSION:+alpha=}$GC_ALPHA_VERSION)
+])
+
 sinclude(libtool.m4)
 
 # Do all the work for Automake.                            -*- Autoconf -*-
@@ -140,7 +188,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"])
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-        [AM_AUTOMAKE_VERSION([1.6.1])])
+        [AM_AUTOMAKE_VERSION([1.6.3])])
 
 # Helper functions for option handling.                    -*- Autoconf -*-
 
@@ -472,7 +520,7 @@ AC_REQUIRE([AM_DEP_TRACK])dnl
 
 ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
        [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
-       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc']
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
        [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
                    [depcc="$$1"   am_compiler_list=])
 
@@ -597,7 +645,13 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 [for mf in $CONFIG_FILES; do
   # Strip MF so we end up with the name of the file.
   mf=`echo "$mf" | sed -e 's/:.*$//'`
-  if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
     dirpart=`AS_DIRNAME("$mf")`
   else
     continue
@@ -821,3 +875,3495 @@ AC_DEFUN([AM_MAINTAINER_MODE],
 ]
 )
 
+# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
+
+# serial 46 AC_PROG_LIBTOOL
+
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+_LT_AC_PROG_ECHO_BACKSLASH
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_SAVE
+     AC_LANG_C
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_RESTORE])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+  # recent cygwin and mingw systems supply a stub DllMain which the user
+  # can override, but on older systems we have to supply one
+  AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+    [AC_TRY_LINK([],
+      [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+      DllMain (0, 0, 0);],
+      [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])])
+
+  case $host/$CC in
+  *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*)
+    # old mingw systems require "-dll" to link a DLL, while more recent ones
+    # require "-mdll"
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mdll"
+    AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+      [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+    CFLAGS="$SAVE_CFLAGS" ;;
+  *-*-cygwin* | *-*-pw32*)
+    # cygwin systems need to pass --dll to the linker, and not link
+    # crt.o which will require a WinMain@16 definition.
+    lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+  esac
+  ;;
+  ])
+esac
+
+_LT_AC_LTCONFIG_HACK
+
+])
+
+# AC_LIBTOOL_HEADER_ASSERT
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT],
+[AC_CACHE_CHECK([whether $CC supports assert without backlinking],
+    [lt_cv_func_assert_works],
+    [case $host in
+    *-*-solaris*)
+      if test "$GCC" = yes && test "$with_gnu_ld" != yes; then
+        case `$CC --version 2>/dev/null` in
+        [[12]].*) lt_cv_func_assert_works=no ;;
+        *)        lt_cv_func_assert_works=yes ;;
+        esac
+      fi
+      ;;
+    esac])
+
+if test "x$lt_cv_func_assert_works" = xyes; then
+  AC_CHECK_HEADERS(assert.h)
+fi
+])# AC_LIBTOOL_HEADER_ASSERT
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)
+])# _LT_AC_CHECK_DLFCN
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix*)
+  symcode='[[BCDEGRST]]'
+  ;;
+solaris* | sysv5*)
+  symcode='[[BDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[[ABCDGISTW]]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[       ]]\($symcode$symcode*\)[[       ]][[    ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+         cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+         sed "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+         cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if AC_TRY_EVAL(ac_link) && test -s conftest; then
+           pipe_works=yes
+         fi
+         LIBS="$save_LIBS"
+         CFLAGS="$save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&AC_FD_CC
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&AC_FD_CC
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC
+    fi
+  else
+    echo "$progname: failed program was:" >&AC_FD_CC
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+  global_symbol_to_c_name_address=
+else
+  global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+  global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+# ---------------------------------
+AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR],
+[# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) lt_cv_sys_path_separator=';' ;;
+    *)     lt_cv_sys_path_separator=':' ;;
+  esac
+  PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+                             [AC_DIVERT_PUSH(NOTICE)])
+_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+        test "X$echo_testing_string" = "X$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+         then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "[$]0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+AC_DIVERT_POP
+])# _LT_AC_PROG_ECHO_BACKSLASH
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_unknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+          [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+            [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+       [AC_CHECK_FUNC([dlopen],
+             [lt_cv_dlopen="dlopen"],
+         [AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+           [AC_CHECK_LIB([svld], [dlopen],
+                 [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+             [AC_CHECK_LIB([dld], [dld_link],
+                   [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+             ])
+           ])
+         ])
+       ])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+         lt_cv_dlopen_self, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+           lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+         lt_cv_dlopen_self_static, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+           lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+AC_DEFUN([_LT_AC_LTCONFIG_HACK],
+[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+  ac_tool_prefix=${host_alias}-
+else
+  ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="[$]2"
+
+AC_MSG_CHECKING([for objdir])
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+AC_MSG_RESULT($objdir)
+
+
+AC_ARG_WITH(pic,
+[  --with-pic              try to use only PIC/non-PIC objects [default=use both]],
+pic_mode="$withval", pic_mode=default)
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+AC_CACHE_VAL(lt_cv_prog_cc_pic,
+[ lt_cv_prog_cc_pic=
+  lt_cv_prog_cc_shlib=
+  lt_cv_prog_cc_wl=
+  lt_cv_prog_cc_static=
+  lt_cv_prog_cc_no_builtin=
+  lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+  if test "$GCC" = yes; then
+    lt_cv_prog_cc_wl='-Wl,'
+    lt_cv_prog_cc_static='-static'
+
+    case $host_os in
+    aix*)
+      # Below there is a dirty hack to force normal static linking with -ldl
+      # The problem is because libdl dynamically linked with both libc and
+      # libC (AIX C++ library), which obviously doesn't included in libraries
+      # list by gcc. This cause undefined symbols with -static flags.
+      # This hack allows C programs to be linked with "-static -ldl", but
+      # not sure about C++ programs.
+      lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_cv_prog_cc_pic='-fno-common'
+      ;;
+    cygwin* | mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_cv_prog_cc_pic='-DDLL_EXPORT'
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+        lt_cv_prog_cc_pic=-Kconform_pic
+      fi
+      ;;
+    *)
+      lt_cv_prog_cc_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for PIC flags for the system compiler.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      lt_cv_prog_cc_wl='-Wl,'
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_cv_prog_cc_static='-Bstatic'
+      else
+       lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+      lt_cv_prog_cc_pic='+Z'
+      ;;
+
+    irix5* | irix6*)
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static='-non_shared'
+      # PIC (with -KPIC) is the default.
+      ;;
+
+    cygwin* | mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_cv_prog_cc_pic='-DDLL_EXPORT'
+      ;;
+
+    newsos6)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      # All OSF/1 code is PIC.
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_cv_prog_cc_pic='-Kpic'
+      lt_cv_prog_cc_static='-dn'
+      lt_cv_prog_cc_shlib='-belf'
+      ;;
+
+    solaris*)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      lt_cv_prog_cc_wl='-Wl,'
+      ;;
+
+    sunos4*)
+      lt_cv_prog_cc_pic='-PIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      lt_cv_prog_cc_wl='-Qoption ld '
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      if test "x$host_vendor" = xsni; then
+       lt_cv_prog_cc_wl='-LD'
+      else
+       lt_cv_prog_cc_wl='-Wl,'
+      fi
+      ;;
+
+    uts4*)
+      lt_cv_prog_cc_pic='-pic'
+      lt_cv_prog_cc_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_cv_prog_cc_pic='-Kconform_pic'
+       lt_cv_prog_cc_static='-Bstatic'
+      fi
+      ;;
+
+    *)
+      lt_cv_prog_cc_can_build_shared=no
+      ;;
+    esac
+  fi
+])
+if test -z "$lt_cv_prog_cc_pic"; then
+  AC_MSG_RESULT([none])
+else
+  AC_MSG_RESULT([$lt_cv_prog_cc_pic])
+
+  # Check to make sure the pic_flag actually works.
+  AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works])
+  AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+    AC_TRY_COMPILE([], [], [dnl
+      case $host_os in
+      hpux9* | hpux10* | hpux11*)
+       # On HP-UX, both CC and GCC only warn that PIC is supported... then
+       # they create non-PIC objects.  So, if there were any warnings, we
+       # assume that PIC is not supported.
+       if test -s conftest.err; then
+         lt_cv_prog_cc_pic_works=no
+       else
+         lt_cv_prog_cc_pic_works=yes
+       fi
+       ;;
+      *)
+       lt_cv_prog_cc_pic_works=yes
+       ;;
+      esac
+    ], [dnl
+      lt_cv_prog_cc_pic_works=no
+    ])
+    CFLAGS="$save_CFLAGS"
+  ])
+
+  if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+    lt_cv_prog_cc_pic=
+    lt_cv_prog_cc_can_build_shared=no
+  else
+    lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+  fi
+
+  AC_MSG_RESULT([$lt_cv_prog_cc_pic_works])
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+  AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries])
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[[        ]]$lt_cv_prog_cc_shlib[[        ]]" >/dev/null; then :
+  else
+   AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure])
+    lt_cv_prog_cc_can_build_shared=no
+  fi
+fi
+
+AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works])
+AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl
+  lt_cv_prog_cc_static_works=no
+  save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+  AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes])
+  LDFLAGS="$save_LDFLAGS"
+])
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+AC_MSG_RESULT([$lt_cv_prog_cc_static_works])
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext])
+AC_CACHE_VAL([lt_cv_compiler_c_o], [
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+  if test -s out/conftest.err; then
+    lt_cv_compiler_c_o=no
+  else
+    lt_cv_compiler_c_o=yes
+  fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&AC_FD_CC
+  lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+])
+compiler_c_o=$lt_cv_compiler_c_o
+AC_MSG_RESULT([$compiler_c_o])
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  AC_MSG_CHECKING([if $compiler supports -c -o file.lo])
+  AC_CACHE_VAL([lt_cv_compiler_o_lo], [
+  lt_cv_compiler_o_lo=no
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  save_objext="$ac_objext"
+  ac_objext=lo
+  AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+    if test -s conftest.err; then
+      lt_cv_compiler_o_lo=no
+    else
+      lt_cv_compiler_o_lo=yes
+    fi
+  ])
+  ac_objext="$save_objext"
+  CFLAGS="$save_CFLAGS"
+  ])
+  compiler_o_lo=$lt_cv_compiler_o_lo
+  AC_MSG_RESULT([$compiler_o_lo])
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$GCC" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions])
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+  compiler_rtti_exceptions=no
+  AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+    if test -s conftest.err; then
+      compiler_rtti_exceptions=no
+    else
+      compiler_rtti_exceptions=yes
+    fi
+  ])
+  CFLAGS="$save_CFLAGS"
+  AC_MSG_RESULT([$compiler_rtti_exceptions])
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+fi
+
+# See if the linker supports building shared libraries.
+AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries])
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$GCC" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+openbsd*)
+  with_gnu_ld=no
+  ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case $host_os in
+  aix3* | aix4* | aix5*)
+    # On AIX, the GNU linker is very broken
+    # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+      sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+      test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+      if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+      else $CC -o impgen impgen.c ; fi)~
+      $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+    old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+    # cygwin and mingw dlls have different entry points and sets of symbols
+    # to exclude.
+    # FIXME: what about values for MSVC?
+    dll_entry=__cygwin_dll_entry@12
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+    case $host_os in
+    mingw*)
+      # mingw values
+      dll_entry=_DllMainCRTStartup@12
+      dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+      ;;
+    esac
+
+    # mingw and cygwin differ, and it's simplest to just exclude the union
+    # of the two symbol sets.
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+    # recent cygwin and mingw systems supply a stub DllMain which the user
+    # can override, but on older systems we have to supply one (in ltdll.c)
+    if test "x$lt_cv_need_dllmain" = "xyes"; then
+      ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+      ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+       test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+    else
+      ltdll_obj=
+      ltdll_cmds=
+    fi
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left be newer dlltools.
+    export_symbols_cmds="$ltdll_cmds"'
+      $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+    # If the export-symbols file already is a .def file (1st line
+    # is EXPORTS), use it as is.
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+       cp $export_symbols $output_objdir/$soname-def;
+      else
+       echo EXPORTS > $output_objdir/$soname-def;
+       _lt_hint=1;
+       cat $export_symbols | while read symbol; do
+        set dummy \$symbol;
+        case \[$]# in
+          2) echo "   \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+          *) echo "     \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
+        esac;
+        _lt_hint=`expr 1 + \$_lt_hint`;
+       done;
+      fi~
+      '"$ltdll_cmds"'
+      $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+      $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+      $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+      wlarc=
+    else
+      archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw* | pw32*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case $host_os in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$GCC" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+       for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+       done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    hardcode_direct=yes
+    archive_cmds=''
+    hardcode_libdir_separator=':'
+    if test "$GCC" = yes; then
+      case $host_os in aix4.[[012]]|aix4.[[012]].*)
+       collect2name=`${CC} -print-prog-name=collect2`
+       if test -f "$collect2name" && \
+         strings "$collect2name" | grep resolve_lib_name >/dev/null
+       then
+         # We have reworked collect2
+         hardcode_direct=yes
+       else
+         # We have old collect2
+         hardcode_direct=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L=yes
+         hardcode_libdir_flag_spec='-L$libdir'
+         hardcode_libdir_separator=
+       fi
+      esac
+
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+       shared_flag='${wl}-G'
+      else
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag='${wl}-G'
+       else
+         shared_flag='${wl}-bM:SRE'
+       fi
+      fi
+    fi
+
+    # It seems that -bexpall can do strange things, so it is better to
+    # generate a list of symbols to export.
+    always_export_symbols=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag='-berok'
+      hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+      archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+    else
+      if test "$host_cpu" = ia64; then
+       hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+       allow_undefined_flag="-z nodefs"
+       archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+       hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+       # Warning - without using the other run time loading flags,
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag='${wl}-berok'
+       # This is a bit strange, but is similar to how AIX traditionally builds
+       # it's shared libraries.
+       archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+      fi
+    fi
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+    fix_srcfile_path='`cygpath -w "$srcfile"`'
+    ;;
+
+  darwin* | rhapsody*)
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      allow_undefined_flag='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      allow_undefined_flag='-flat_namespace -undefined suppress'
+      ;;
+    esac
+    # FIXME: Relying on posixy $() will cause problems for
+    #        cross-compilation, but unfortunately the echo tests do not
+    #        yet detect zsh echo's removal of \ escapes.
+    archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case $host_os in
+    hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$GCC" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    link_all_deplibs=yes
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+    fi
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  newsos6)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+    else
+      case "$host_os" in
+      openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+       archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+        ;;
+      *)
+        archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+        hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+        ;;
+      esac
+    fi
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$GCC" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)       # as osf3* with the addition of -msym flag
+    if test "$GCC" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+      $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+      #Both c and cxx compiler support -rpath directly
+      hardcode_libdir_flag_spec='-rpath $libdir'
+    fi
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    export_dynamic_flag_spec='${wl}-Bexport'
+    ;;
+
+  solaris*)
+    # gcc --version < 3.0 without binutils cannot create self contained
+    # shared libraries reliably, requiring libgcc.a to resolve some of
+    # the object symbols generated in some cases.  Libraries that use
+    # assert need libgcc.a to resolve __eprintf, for example.  Linking
+    # a copy of libgcc.a into every shared library to guarantee resolving
+    # such symbols causes other problems:  According to Tim Van Holder
+    # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+    # (to the application) exception stack for one thing.
+    no_undefined_flag=' -z defs'
+    if test "$GCC" = yes; then
+      case `$CC --version 2>/dev/null` in
+      [[12]].*)
+       cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a.  Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries.  However, you may find that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command.  We urge you to
+*** upgrade to a newer version of GCC.  Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+        no_undefined_flag=
+       ;;
+      esac
+    fi
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case $host_os in
+    solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    link_all_deplibs=yes
+    ;;
+
+  sunos4*)
+    if test "x$host_vendor" = xsequent; then
+      # Use $CC to link under sequent, because it throws in some extra .o
+      # files that make .init and .fini sections work.
+      archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+    else
+      archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+    fi
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    if test "x$host_vendor" = xsno; then
+      archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes # is this really true???
+    else
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  sysv5uw7* | unixware7*)
+    no_undefined_flag='${wl}-z ${wl}text'
+    if test "$GCC" = yes; then
+      archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+    else
+      archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+AC_MSG_RESULT([$ld_shlibs])
+test "$ld_shlibs" = no && can_build_shared=no
+
+# Check hardcoding attributes.
+AC_MSG_CHECKING([how to hardcode library paths into programs])
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+AC_MSG_RESULT([$hardcode_action])
+
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+  AC_MSG_RESULT([no])
+fi
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+# PORTME Fill in your ld.so characteristics
+AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+            echo ' yes '
+            echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+         :
+       else
+         can_build_shared=no
+       fi
+       ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can
+    # not hardcode correct soname into executable. Probably we can
+    # add versioning support to collect2, so additional links can
+    # be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}.so$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  case $GCC,$host_os in
+  yes,cygwin*)
+    library_names_spec='$libname.dll.a'
+    soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+    postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog .libs/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    ;;
+  yes,mingw*)
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+    sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+    ;;
+  yes,pw32*)
+    library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+    ;;
+  *)
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  # FIXME: Relying on posixy $() will cause problems for
+  #        cross-compilation, but unfortunately the echo tests do not
+  #        yet detect zsh echo's removal of \ escapes.
+  library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+  soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+  case $host_os in
+  irix5*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case "$host_os" in
+    openbsd2.[[89]] | openbsd2.[[89]].*)
+      shlibpath_overrides_runpath=no
+      ;;
+    *)
+      shlibpath_overrides_runpath=yes
+      ;;
+    esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+AC_LIBTOOL_DLOPEN_SELF
+
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+  case $archive_cmds in
+  *'~'*)
+    # FIXME: we may have to deal with multi-command sequences.
+    ;;
+  '$CC '*)
+    # Test whether the compiler implicitly links with -lc since on some
+    # systems, -lgcc has to come before -lc. If gcc already passes -lc
+    # to ld, don't add -lc before -lgcc.
+    AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+    AC_CACHE_VAL([lt_cv_archive_cmds_need_lc],
+    [$rm conftest*
+    echo 'static int dummy;' > conftest.$ac_ext
+
+    if AC_TRY_EVAL(ac_compile); then
+      soname=conftest
+      lib=conftest
+      libobjs=conftest.$ac_objext
+      deplibs=
+      wl=$lt_cv_prog_cc_wl
+      compiler_flags=-v
+      linker_flags=-v
+      verstring=
+      output_objdir=.
+      libname=conftest
+      save_allow_undefined_flag=$allow_undefined_flag
+      allow_undefined_flag=
+      if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+      then
+       lt_cv_archive_cmds_need_lc=no
+      else
+       lt_cv_archive_cmds_need_lc=yes
+      fi
+      allow_undefined_flag=$save_allow_undefined_flag
+    else
+      cat conftest.err 1>&5
+    fi])
+    AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc])
+    ;;
+  esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  :
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+  trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+  $rm -f "${ofile}T"
+
+  echo creating $ofile
+
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS \
+    AR AR_FLAGS CC LD LN_S NM SHELL \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+    postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+    old_striplib striplib file_magic_cmd export_symbols_cmds \
+    deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    global_symbol_to_c_name_address \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case $var in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | os2*)
+    cat <<'EOF' >> "${ofile}T"
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+       # This is a source program that is used to create import libraries
+       # on Windows for dlls which lack them. Don't remove nor modify the
+       # starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+#  This file is part of GNU libtool.
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#  */
+#
+# #include <stdio.h>           /* for printf() */
+# #include <unistd.h>          /* for open(), lseek(), read() */
+# #include <fcntl.h>           /* for O_RDONLY, O_BINARY */
+# #include <string.h>          /* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+#      int fd;
+#      int offset;
+# {
+#   unsigned char b[2];
+#   lseek (fd, offset, SEEK_SET);
+#   read (fd, b, 2);
+#   return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+#     int fd;
+#     int offset;
+# {
+#   unsigned char b[4];
+#   lseek (fd, offset, SEEK_SET);
+#   read (fd, b, 4);
+#   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+#      void *ptr;
+# {
+#   unsigned char *b = ptr;
+#   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+#     int argc;
+#     char *argv[];
+# {
+#     int dll;
+#     unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#     unsigned long export_rva, export_size, nsections, secptr, expptr;
+#     unsigned long name_rvas, nexp;
+#     unsigned char *expdata, *erva;
+#     char *filename, *dll_name;
+#
+#     filename = argv[1];
+#
+#     dll = open(filename, O_RDONLY|O_BINARY);
+#     if (dll < 1)
+#      return 1;
+#
+#     dll_name = filename;
+#
+#     for (i=0; filename[i]; i++)
+#      if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+#          dll_name = filename + i +1;
+#
+#     pe_header_offset = pe_get32 (dll, 0x3c);
+#     opthdr_ofs = pe_header_offset + 4 + 20;
+#     num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+#     if (num_entries < 1) /* no exports */
+#      return 1;
+#
+#     export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#     export_size = pe_get32 (dll, opthdr_ofs + 100);
+#     nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#     secptr = (pe_header_offset + 4 + 20 +
+#            pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+#     expptr = 0;
+#     for (i = 0; i < nsections; i++)
+#     {
+#      char sname[8];
+#      unsigned long secptr1 = secptr + 40 * i;
+#      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+#      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+#      unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+#      lseek(dll, secptr1, SEEK_SET);
+#      read(dll, sname, 8);
+#      if (vaddr <= export_rva && vaddr+vsize > export_rva)
+#      {
+#          expptr = fptr + (export_rva - vaddr);
+#          if (export_rva + export_size > vaddr + vsize)
+#              export_size = vsize - (export_rva - vaddr);
+#          break;
+#      }
+#     }
+#
+#     expdata = (unsigned char*)malloc(export_size);
+#     lseek (dll, expptr, SEEK_SET);
+#     read (dll, expdata, export_size);
+#     erva = expdata - export_rva;
+#
+#     nexp = pe_as32 (expdata+24);
+#     name_rvas = pe_as32 (expdata+32);
+#
+#     printf ("EXPORTS\n");
+#     for (i = 0; i<nexp; i++)
+#     {
+#      unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+#      printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#     }
+#
+#     return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+  mv -f "${ofile}T" "$ofile" || \
+    (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+  chmod +x "$ofile"
+fi
+
+])# _LT_AC_LTCONFIG_HACK
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+#   Where MODE is either `yes' or `no'.  If omitted, it defaults to
+#   `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)])
+
+
+# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           egrep "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  MAGIC_CMD="$ac_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])
+
+
+# AC_PATH_MAGIC - find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl
+AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | [[A-Za-z]]:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+# AC_PROG_LD_GNU -
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  lt_cv_prog_gnu_ld=yes
+else
+  lt_cv_prog_gnu_ld=no
+fi])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])
+
+# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag,
+[lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+])
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependant libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin* | mingw* | pw32*)
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  case "$host_os" in
+  rhapsody* | darwin1.[[012]])
+    lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+    ;;
+  *) # Darwin 1.3 on
+    lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+    ;;
+  esac
+  ;;
+
+freebsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20*|hpux11*)
+  lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libc.sl
+  ;;
+
+irix5* | irix6*)
+  case $host_os in
+  irix5*)
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case $LD in
+    *-32|*"-32 ") libmagic=32-bit;;
+    *-n32|*"-n32 ") libmagic=N32;;
+    *-64|*"-64 ") libmagic=64-bit;;
+    *) libmagic=never-match;;
+    esac
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1"
+    ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  case $host_cpu in
+  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* )
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  # this will be overridden with pass_all, but let us keep it just in case
+  lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  lt_cv_file_magic_test_file=/lib/libc.so
+  ;;
+
+sysv5uw[[78]]* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  esac
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+])
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm=$ac_dir/${ac_tool_prefix}nm
+    if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+       lt_cv_path_NM="$tmp_nm -B"
+       break
+      elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       lt_cv_path_NM="$tmp_nm -p"
+       break
+      else
+       lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments.  Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If DIR is not
+# provided, it is assumed to be `libltdl'.  LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments.  Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called.  If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!).  If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
similarity index 70%
rename from irix_threads.c
rename to aix_irix_threads.c
index 48173e446f511bfcace67ea9fdf44ed4ed081f14..d3e8ae0f2dbca6479c92c6434502b66a77261713 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
  * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved.
- * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved.
+ * Copyright (c) 1999-2003 by Hewlett-Packard Company. All rights reserved.
  *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  * modified is included with the above copyright notice.
  */
 /*
- * Support code for Irix (>=6.2) Pthreads.  This relies on properties
+ * Support code for Irix (>=6.2) Pthreads and for AIX pthreads.
+ * This relies on properties
  * not guaranteed by the Pthread standard.  It may or may not be portable
  * to other implementations.
  *
- * This now also includes an initial attempt at thread support for
- * HP/UX 11.
+ * Note that there is a lot of code duplication between this file and
+ * (pthread_support.c, pthread_stop_world.c).  They should be merged.
+ * Pthread_support.c should be directly usable.
  *
- * Note that there is a lot of code duplication between linux_threads.c
- * and irix_threads.c; any changes made here may need to be reflected
- * there too.
+ * Please avoid adding new ports here; use the generic pthread support
+ * as a base instead.
  */
 
-# if defined(GC_IRIX_THREADS)
+# if defined(GC_IRIX_THREADS) || defined(GC_AIX_THREADS)
 
 # include "private/gc_priv.h"
 # include <pthread.h>
+# include <assert.h>
 # include <semaphore.h>
 # include <time.h>
 # include <errno.h>
 #undef pthread_create
 #undef pthread_sigmask
 #undef pthread_join
-#undef pthread_detach
 
-#ifdef HANDLE_FORK
-  --> Not yet supported.  Try porting the code from linux_threads.c.
+#if defined(GC_IRIX_THREADS) && !defined(MUTEX_RECURSIVE_NP)
+#define MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
 #endif
 
 void GC_thr_init();
@@ -104,8 +105,14 @@ GC_thread GC_lookup_thread(pthread_t id);
  * The only way to suspend threads given the pthread interface is to send
  * signals.  Unfortunately, this means we have to reserve
  * a signal, and intercept client calls to change the signal mask.
- * We use SIG_SUSPEND, defined in gc_priv.h.
  */
+#if 0 /* DOB: 6.1 */
+# if defined(GC_AIX_THREADS)
+#   define SIG_SUSPEND SIGUSR1
+# else
+#   define SIG_SUSPEND (SIGRTMIN + 6)
+# endif
+#endif
 
 pthread_mutex_t GC_suspend_lock = PTHREAD_MUTEX_INITIALIZER;
                                /* Number of threads stopped so far     */
@@ -145,6 +152,8 @@ GC_bool GC_thr_initialized = FALSE;
 
 size_t GC_min_stack_sz;
 
+size_t GC_page_sz;
+
 # define N_FREE_LISTS 25
 ptr_t GC_stack_free_lists[N_FREE_LISTS] = { 0 };
                /* GC_stack_free_lists[i] is free list for stacks of    */
@@ -173,14 +182,14 @@ ptr_t GC_stack_alloc(size_t * stack_size)
     if (result != 0) {
         GC_stack_free_lists[index] = *(ptr_t *)result;
     } else {
-        result = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_size);
-        result = (ptr_t)(((word)result + GC_page_size) & ~(GC_page_size - 1));
+        result = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_sz);
+        result = (ptr_t)(((word)result + GC_page_sz) & ~(GC_page_sz - 1));
         /* Protect hottest page to detect overflow. */
 #      ifdef STACK_GROWS_UP
-          /* mprotect(result + search_sz, GC_page_size, PROT_NONE); */
+          /* mprotect(result + search_sz, GC_page_sz, PROT_NONE); */
 #      else
-          /* mprotect(result, GC_page_size, PROT_NONE); */
-          result += GC_page_size;
+          /* mprotect(result, GC_page_sz, PROT_NONE); */
+          result += GC_page_sz;
 #      endif
     }
     *stack_size = search_sz;
@@ -227,7 +236,7 @@ GC_thread GC_new_thread(pthread_t id)
        /* Dont acquire allocation lock, since we may already hold it. */
     } else {
         result = (struct GC_Thread_Rep *)
-                GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep), NORMAL);
+                GC_generic_malloc_inner(sizeof(struct GC_Thread_Rep), NORMAL);
     }
     if (result == 0) return(0);
     result -> id = id;
@@ -294,6 +303,42 @@ GC_thread GC_lookup_thread(pthread_t id)
     return(p);
 }
 
+#if defined(GC_AIX_THREADS)
+void GC_stop_world()
+{
+    pthread_t my_thread = pthread_self();
+    register int i;
+    register GC_thread p;
+    register int result;
+    struct timespec timeout;
+
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+      for (p = GC_threads[i]; p != 0; p = p -> next) {
+        if (p -> id != my_thread) {
+          pthread_suspend_np(p->id);
+        }
+      }
+    }
+    /* GC_printf1("World stopped 0x%x\n", pthread_self()); */
+}
+
+void GC_start_world()
+{
+    GC_thread p;
+    unsigned i;
+    pthread_t my_thread = pthread_self();
+
+    /* GC_printf0("World starting\n"); */
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+      for (p = GC_threads[i]; p != 0; p = p -> next) {
+        if (p -> id != my_thread) {
+          pthread_continue_np(p->id);
+        }
+      }
+    }
+}
+
+#else /* GC_AIX_THREADS */
 
 /* Caller holds allocation lock.       */
 void GC_stop_world()
@@ -371,6 +416,8 @@ void GC_start_world()
     pthread_cond_broadcast(&GC_continue_cv);
 }
 
+#endif /* GC_AIX_THREADS */
+
 # ifdef MMAP_STACKS
 --> not really supported yet.
 int GC_is_thread_stack(ptr_t addr)
@@ -409,7 +456,41 @@ void GC_push_all_stacks()
         if (pthread_equal(p -> id, me)) {
            hot = GC_approx_sp();
        } else {
-           hot = p -> stack_ptr;
+#ifdef GC_AIX_THREADS
+          /* AIX doesn't use signals to suspend, so we need to get an accurate hot stack pointer */
+          pthread_t id = p -> id;
+          struct __pthrdsinfo pinfo;
+          int val = 255;
+          char regbuf[255];
+          int retval = pthread_getthrds_np(&id, PTHRDSINFO_QUERY_ALL, &pinfo, sizeof(pinfo), regbuf, &val);
+          if (retval != 0) { printf("ERROR: pthread_getthrds_np() failed in GC\n"); abort(); }
+          hot = (ptr_t)(unsigned long)pinfo.__pi_ustk;
+          if ((p -> stack_size != 0 && 
+               (pinfo.__pi_stackend != ((ptr_t)p -> stack) + p -> stack_size || 
+                p -> stack_ptr < p -> stack || 
+                p -> stack_ptr > ((ptr_t)p -> stack) + p -> stack_size))) {
+            printf("ERROR in GC_push_all_stacks() stack state:\n"
+                "p->stack:                 0x%08x\n"
+                "p->stack_size:            0x%08x\n"
+                "p->stack_ptr:             0x%08x\n"
+                "(p->stack+p->stack_size): 0x%08x\n"
+                "pinfo.__pi_stackaddr:     0x%08x\n"
+                "pinfo.__pi_stacksize:     0x%08x\n"
+                "pinfo.__pi_stackend:      0x%08x\n"
+                "GC_stackbottom:           0x%08x\n"
+                ,
+                (uintptr_t)p->stack, (uintptr_t)p->stack_size, 
+                (uintptr_t)p->stack_ptr, (uintptr_t)(((ptr_t)(p->stack))+p->stack_size),
+                (uintptr_t)pinfo.__pi_stackaddr, (uintptr_t)pinfo.__pi_stacksize, (uintptr_t)pinfo.__pi_stackend,
+                (uintptr_t)GC_stackbottom
+                );
+          }
+          /* push the registers too, because they won't be on stack */
+          GC_push_all_eager((ptr_t)&pinfo.__pi_context, (ptr_t)((&pinfo.__pi_context)+1));
+          GC_push_all_eager((ptr_t)regbuf, (ptr_t)&regbuf[val]);
+#else
+              hot = p -> stack_ptr;
+#endif
        }
         if (p -> stack_size != 0) {
 #        ifdef STACK_GROWS_UP
@@ -424,6 +505,7 @@ void GC_push_all_stacks()
 #      ifdef STACK_GROWS_UP
           GC_push_all_stack(cold, hot);
 #      else
+ /* printf("thread 0x%x: hot=0x%08x cold=0x%08x\n", p -> id, hot, cold); */
           GC_push_all_stack(hot, cold);
 #      endif
       }
@@ -440,6 +522,8 @@ void GC_thr_init()
     if (GC_thr_initialized) return;
     GC_thr_initialized = TRUE;
     GC_min_stack_sz = HBLKSIZE;
+    GC_page_sz = sysconf(_SC_PAGESIZE);
+#ifndef GC_AIX_THREADS
     (void) sigaction(SIG_SUSPEND, 0, &act);
     if (act.sa_handler != SIG_DFL)
        ABORT("Previously installed SIG_SUSPEND handler");
@@ -449,6 +533,7 @@ void GC_thr_init()
        (void) sigemptyset(&act.sa_mask);
         if (0 != sigaction(SIG_SUSPEND, &act, 0))
            ABORT("Failed to install SIG_SUSPEND handler");
+#endif
     /* Add the initial thread, so we can stop it.      */
       t = GC_new_thread(pthread_self());
       t -> stack_size = 0;
@@ -460,6 +545,10 @@ int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
 {
     sigset_t fudged_set;
     
+#ifdef GC_AIX_THREADS
+    return(pthread_sigmask(how, set, oset));
+#endif
+
     if (set != NULL && (how == SIG_BLOCK || how == SIG_SETMASK)) {
         fudged_set = *set;
         sigdelset(&fudged_set, SIG_SUSPEND);
@@ -474,8 +563,9 @@ struct start_info {
     word flags;
     ptr_t stack;
     size_t stack_size;
-    sem_t registered;          /* 1 ==> in our thread table, but       */
-                               /* parent hasn't yet noticed.           */
+    pthread_mutex_t registeredlock;
+    pthread_cond_t registered;     
+    int volatile registereddone;
 };
 
 void GC_thread_exit_proc(void *arg)
@@ -506,33 +596,10 @@ int GC_pthread_join(pthread_t thread, void **retval)
     /* Some versions of the Irix pthreads library can erroneously      */
     /* return EINTR when the call succeeds.                            */
        if (EINTR == result) result = 0;
-    if (result == 0) {
-        LOCK();
-        /* Here the pthread thread id may have been recycled. */
-        GC_delete_gc_thread(thread, thread_gc_id);
-        UNLOCK();
-    }
-    return result;
-}
-
-int GC_pthread_detach(pthread_t thread)
-{
-    int result;
-    GC_thread thread_gc_id;
-    
     LOCK();
-    thread_gc_id = GC_lookup_thread(thread);
+    /* Here the pthread thread id may have been recycled. */
+    GC_delete_gc_thread(thread, thread_gc_id);
     UNLOCK();
-    result = pthread_detach(thread);
-    if (result == 0) {
-      LOCK();
-      thread_gc_id -> flags |= DETACHED;
-      /* Here the pthread thread id may have been recycled. */
-      if (thread_gc_id -> flags & FINISHED) {
-        GC_delete_gc_thread(thread, thread_gc_id);
-      }
-      UNLOCK();
-    }
     return result;
 }
 
@@ -562,15 +629,24 @@ void * GC_start_routine(void * arg)
     me -> flags = si -> flags;
     me -> stack = si -> stack;
     me -> stack_size = si -> stack_size;
+#ifdef STACK_GROWS_UP
     me -> stack_ptr = (ptr_t)si -> stack + si -> stack_size - sizeof(word);
+#else
+    /* stack_ptr needs to point to the hot part of the stack (or conservatively, past it) */
+    me -> stack_ptr = (ptr_t)si -> stack;
+#endif
     UNLOCK();
     start = si -> start_routine;
     start_arg = si -> arg;
-    sem_post(&(si -> registered));
+
+    pthread_mutex_lock(&(si->registeredlock));
+    si->registereddone = 1;
+    pthread_cond_signal(&(si->registered));
+    pthread_mutex_unlock(&(si->registeredlock));
+
     pthread_cleanup_push(GC_thread_exit_proc, 0);
     result = (*start)(start_arg);
     me -> status = result;
-    me -> flags |= FINISHED;
     pthread_cleanup_pop(1);
        /* This involves acquiring the lock, ensuring that we can't exit */
        /* while a collection that thinks we're alive is trying to stop  */
@@ -578,7 +654,43 @@ void * GC_start_routine(void * arg)
     return(result);
 }
 
-# define copy_attr(pa_ptr, source) *(pa_ptr) = *(source)
+# if defined(GC_AIX_THREADS)
+  /* pthread_attr_t is not a structure, thus a simple structure copy   */
+  /* won't work.                                                       */
+  static void copy_attr(pthread_attr_t * pa_ptr,
+                       const pthread_attr_t  * source) {
+    int tmp;
+    size_t stmp;
+    void * vtmp;
+    struct sched_param sp_tmp;
+#ifndef GC_AIX_THREADS
+    pthread_spu_t ps_tmp;
+#endif
+    (void) pthread_attr_init(pa_ptr);
+    (void) pthread_attr_getdetachstate(source, &tmp);
+    (void) pthread_attr_setdetachstate(pa_ptr, tmp);
+    (void) pthread_attr_getinheritsched(source, &tmp);
+    (void) pthread_attr_setinheritsched(pa_ptr, tmp);
+    (void) pthread_attr_getschedpolicy(source, &tmp);
+    (void) pthread_attr_setschedpolicy(pa_ptr, tmp);
+    (void) pthread_attr_getstacksize(source, &stmp);
+    (void) pthread_attr_setstacksize(pa_ptr, stmp);
+    (void) pthread_attr_getguardsize(source, &stmp);
+    (void) pthread_attr_setguardsize(pa_ptr, stmp);
+    (void) pthread_attr_getstackaddr(source, &vtmp);
+    (void) pthread_attr_setstackaddr(pa_ptr, vtmp);
+    (void) pthread_attr_getscope(source, &tmp);
+    (void) pthread_attr_setscope(pa_ptr, tmp);
+    (void) pthread_attr_getschedparam(source, &sp_tmp);
+    (void) pthread_attr_setschedparam(pa_ptr, &sp_tmp);
+#ifndef GC_AIX_THREADS
+    (void) pthread_attr_getprocessor_np(source, &ps_tmp, &tmp);
+    (void) pthread_attr_setprocessor_np(pa_ptr, ps_tmp, tmp);
+#endif
+  }
+# else
+#   define copy_attr(pa_ptr, source) *(pa_ptr) = *(source)
+# endif
 
 int
 GC_pthread_create(pthread_t *new_thread,
@@ -593,17 +705,18 @@ GC_pthread_create(pthread_t *new_thread,
     int detachstate;
     word my_flags = 0;
     struct start_info * si = GC_malloc(sizeof(struct start_info)); 
-       /* This is otherwise saved only in an area mmapped by the thread */
-       /* library, which isn't visible to the collector.                */
+
+    /* This is otherwise saved only in an area mmapped by the thread */
+    /* library, which isn't visible to the collector.           */
 
     if (0 == si) return(ENOMEM);
-    if (0 != sem_init(&(si -> registered), 0, 0)) {
-        ABORT("sem_init failed");
-    }
+    pthread_mutex_init(&(si->registeredlock), NULL);
+    pthread_cond_init(&(si->registered),NULL);
     si -> start_routine = start_routine;
     si -> arg = arg;
     LOCK();
-    if (!GC_is_initialized) GC_init();
+    if (!GC_thr_initialized) GC_thr_init();
+
     if (NULL == attr) {
         stack = 0;
        (void) pthread_attr_init(&new_attr);
@@ -613,43 +726,65 @@ GC_pthread_create(pthread_t *new_thread,
     }
     pthread_attr_getstacksize(&new_attr, &stacksize);
     pthread_attr_getdetachstate(&new_attr, &detachstate);
-    if (stacksize < GC_min_stack_sz) ABORT("Stack too small");
-    if (0 == stack) {
-       stack = (void *)GC_stack_alloc(&stacksize);
-       if (0 == stack) {
-           UNLOCK();
-           return(ENOMEM);
-       }
-       pthread_attr_setstackaddr(&new_attr, stack);
+#ifdef GC_AIX_THREADS
+    GC_min_stack_sz = 5*1048576;
+    if (stacksize < GC_min_stack_sz) {
+      stacksize = GC_min_stack_sz;
+    }
+    { int alignment = 16*1024; /* size must be multiple of 16KB greater than 56KB */
+      int minval = 56*1024;
+      if ((stacksize - minval) % alignment != 0) {
+        stacksize = minval + alignment * ((stacksize-minval)/alignment + 1);
+      }
+    }
+#endif
+    if (0 == stack) { 
+      stack = (void *)GC_stack_alloc(&stacksize);
+      if (0 == stack) {
+       UNLOCK();
+       return(ENOMEM);
+      }
+      pthread_attr_setstacksize(&new_attr, stacksize);
+#ifdef GC_AIX_THREADS
+      pthread_attr_setstackaddr(&new_attr, ((char *)stack)+stacksize);
+#else
+      pthread_attr_setstackaddr(&new_attr, stack);
+#endif
     } else {
-       my_flags |= CLIENT_OWNS_STACK;
+      my_flags |= CLIENT_OWNS_STACK;
     }
+
     if (PTHREAD_CREATE_DETACHED == detachstate) my_flags |= DETACHED;
     si -> flags = my_flags;
     si -> stack = stack;
     si -> stack_size = stacksize;
-    result = pthread_create(new_thread, &new_attr, GC_start_routine, si);
+    result = pthread_create(new_thread, &new_attr, GC_start_routine, si); 
+
     if (0 == new_thread && !(my_flags & CLIENT_OWNS_STACK)) {
        GC_stack_free(stack, stacksize);
-    }        
+    } 
     UNLOCK();  
     /* Wait until child has been added to the thread table.            */
     /* This also ensures that we hold onto si until the child is done  */
     /* with it.  Thus it doesn't matter whether it is otherwise                */
     /* visible to the collector.                                       */
-        while (0 != sem_wait(&(si -> registered))) {
-         if (errno != EINTR) {
-           GC_printf1("Sem_wait: errno = %ld\n", (unsigned long) errno);
-           ABORT("sem_wait failed");
-         }
-       }
-        sem_destroy(&(si -> registered));
-    pthread_attr_destroy(&new_attr);  /* Probably unnecessary under Irix */
+
+    si->registereddone = 0;
+    pthread_mutex_lock(&(si->registeredlock));
+    while (!si->registereddone) 
+      pthread_cond_wait(&(si->registered), &(si->registeredlock));
+    pthread_mutex_unlock(&(si->registeredlock));
+
+    pthread_cond_destroy(&(si->registered));
+    pthread_mutex_destroy(&(si->registeredlock));
+    pthread_attr_destroy(&new_attr);  
+
     return(result);
 }
 
-VOLATILE GC_bool GC_collecting = 0;
-                       /* A hint that we're in the collector and       */
+/* For now we use the pthreads locking primitives on HP/UX */
+
+VOLATILE GC_bool GC_collecting = 0; /* A hint that we're in the collector and       */
                         /* holding the allocation lock for an           */
                         /* extended period.                             */
 
@@ -658,9 +793,9 @@ VOLATILE GC_bool GC_collecting = 0;
 
 #define SLEEP_THRESHOLD 3
 
-unsigned long GC_allocate_lock = 0;
-# define GC_TRY_LOCK() !GC_test_and_set(&GC_allocate_lock)
-# define GC_LOCK_TAKEN GC_allocate_lock
+volatile unsigned int GC_allocate_lock = 0;
+#define GC_TRY_LOCK() !GC_test_and_set(&GC_allocate_lock)
+#define GC_LOCK_TAKEN GC_allocate_lock
 
 void GC_lock()
 {
@@ -720,11 +855,11 @@ yield:
     }
 }
 
-# else
+# else  /* !GC_IRIX_THREADS && !GC_AIX_THREADS */
 
 #ifndef LINT
   int GC_no_Irix_threads;
 #endif
 
-# endif /* GC_IRIX_THREADS */
+# endif /* IRIX_THREADS */
 
diff --git a/alloc.c b/alloc.c
index f732444a06c61dbf2aac88f385be2a3dafa982be..d2b874fc7704b352556cd934af1933645820bf9a 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -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[] =
@@ -249,7 +256,6 @@ void GC_maybe_gc()
 
     if (GC_should_collect()) {
         if (!GC_incremental) {
-           GC_notify_full_gc();
             GC_gcollect_inner();
             n_partial_gcs = 0;
             return;
@@ -301,6 +307,7 @@ 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;
@@ -308,6 +315,7 @@ 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
       if (GC_print_stats) {
@@ -321,6 +329,7 @@ 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);
@@ -396,6 +405,7 @@ int n;
 {
     register int i;
     
+    if (GC_dont_gc) return;
     if (GC_incremental && GC_collection_in_progress()) {
        for (i = GC_deficit; i < GC_RATE*n; i++) {
            if (GC_mark_some((ptr_t)0)) {
@@ -462,8 +472,12 @@ GC_stop_func stop_func;
 #   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 ",
@@ -494,6 +508,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);
            }
@@ -527,6 +542,7 @@ GC_stop_func stop_func;
             (*GC_check_heap)();
         }
     
+    IF_THREADS(GC_world_stopped = FALSE);
     START_WORLD();
 #   ifdef PRINTTIMES
        GET_TIME(current_time);
@@ -759,7 +775,6 @@ void GC_finish_collection()
 
 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();
 }
@@ -963,7 +978,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)
@@ -988,7 +1002,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)
@@ -1026,7 +1039,7 @@ int kind;
     while (*flh == 0) {
       ENTER_GC();
       /* Do our share of marking work */
-        if(TRUE_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);
       EXIT_GC();
@@ -1048,6 +1061,8 @@ int kind;
        EXIT_GC();
       }
     }
+    /* Successful allocation; reset failure count.     */
+    GC_fail_count = 0;
     
     return(*flh);
 }
index 01ab738f2f2316d57d01f86e94a956932aa3b9d8..0fe1c8f7d3609f8207634b025a41b69391921692 100644 (file)
@@ -307,6 +307,7 @@ static void add_back_edges(ptr_t p, word n_words, word gc_descr)
     }
   while (currentp < (word *)(p + gc_descr)) {
     word current = *currentp++;
+    FIXUP_POINTER(current);
     if (current >= (word)GC_least_plausible_heap_addr && 
        current <= (word)GC_greatest_plausible_heap_addr) {
        ptr_t target = GC_base((GC_PTR)current);
index 2483548e34c10071b5ab8e891170ac316a28aa51..7fdfcd532481cc4a12efdc365dfb4a5c007be844 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,10 +1,11 @@
 #! /bin/sh
+# From configure.in Revision: 1.2 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by Autoconf 2.52 for gc 6.1.
+# Generated by GNU Autoconf 2.53 for gc 6.2.
 #
-# Report bugs to <Hans_Boehm@hp.com>.
+# Report bugs to <Hans.Boehm@hp.com>.
 #
-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
 # Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
@@ -20,6 +21,7 @@ if test "X${PATH_SEPARATOR+set}" != Xset; then
   PATH_SEPARATOR=$lt_cv_sys_path_separator
 fi
 
+
 # Check that we are running under the correct shell.
 SHELL=${CONFIG_SHELL-/bin/sh}
 
@@ -165,18 +167,18 @@ if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
    ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
 fi
 
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
 
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
 
 # Be Bourne compatible
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
@@ -186,8 +188,165 @@ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
   set -o posix
 fi
 
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
 # Name of the executable.
-as_me=`echo "$0" |sed 's,.*[\\/],,'`
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
 
 if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
@@ -215,22 +374,12 @@ rm -f conf$$ conf$$.exe conf$$.file
 
 as_executable_p="test -f"
 
-# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
-fi
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
 
-# NLS nuisances.
-$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; }
-$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; }
-$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; }
-$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; }
-$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; }
-$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; }
-$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; }
-$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; }
 
 # IFS
 # We need space, tab and new line, in precisely that order.
@@ -239,7 +388,8 @@ as_nl='
 IFS="  $as_nl"
 
 # CDPATH.
-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; }
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+
 
 # Name of the host.
 # hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
@@ -254,7 +404,8 @@ exec 6>&1
 ac_default_prefix=/usr/local
 cross_compiling=no
 subdirs=
-MFLAGS= MAKEFLAGS=
+MFLAGS=
+MAKEFLAGS=
 SHELL=${CONFIG_SHELL-/bin/sh}
 
 # Maximum number of lines to put in a shell here document.
@@ -262,7 +413,51 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # only ac_max_sed_lines should be used.
 : ${ac_max_here_lines=38}
 
+# Identity of this package.
+PACKAGE_NAME='gc'
+PACKAGE_TARNAME='gc'
+PACKAGE_VERSION='6.2'
+PACKAGE_STRING='gc 6.2'
+PACKAGE_BUGREPORT='Hans.Boehm@hp.com'
+
 ac_unique_file="gcj_mlc.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
 
 # Initialize some variables set by options.
 ac_init_help=
@@ -302,13 +497,6 @@ oldincludedir='/usr/include'
 infodir='${prefix}/info'
 mandir='${prefix}/man'
 
-# Identity of this package.
-PACKAGE_NAME='gc'
-PACKAGE_TARNAME='gc'
-PACKAGE_VERSION='6.1'
-PACKAGE_STRING='gc 6.1'
-PACKAGE_BUGREPORT='Hans_Boehm@hp.com'
-
 ac_prev=
 for ac_option
 do
@@ -441,7 +629,7 @@ do
     with_fp=no ;;
 
   -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c)
+  | --no-cr | --no-c | -n)
     no_create=yes ;;
 
   -no-recursion | --no-recursion | --no-recursio | --no-recursi \
@@ -620,7 +808,7 @@ do
   eval ac_val=$`echo $ac_var`
   case $ac_val in
     [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
-    *)  { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
    { (exit 1); exit 1; }; };;
   esac
 done
@@ -632,18 +820,19 @@ do
   eval ac_val=$`echo $ac_var`
   case $ac_val in
     [\\/$]* | ?:[\\/]* ) ;;
-    *)  { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
    { (exit 1); exit 1; }; };;
   esac
 done
 
 # There might be people who depend on the old broken behavior: `$host'
 # used to hold the argument of --host etc.
+# FIXME: To remove some day.
 build=$build_alias
 host=$host_alias
 target=$target_alias
 
-# FIXME: should be removed in autoconf 3.0.
+# FIXME: To remove some day.
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
@@ -659,13 +848,23 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias-
 
 test "$silent" = yes && exec 6>/dev/null
 
+
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
   # Try the directory containing this script, then its parent.
-  ac_prog=$0
-  ac_confdir=`echo "$ac_prog" | sed 's%[\\/][^\\/][^\\/]*$%%'`
-  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
   srcdir=$ac_confdir
   if test ! -r $srcdir/$ac_unique_file; then
     srcdir=..
@@ -675,10 +874,10 @@ else
 fi
 if test ! -r $srcdir/$ac_unique_file; then
   if test "$ac_srcdir_defaulted" = yes; then
-    { echo "$as_me: error: cannot find sources in $ac_confdir or .." >&2
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
    { (exit 1); exit 1; }; }
   else
-    { echo "$as_me: error: cannot find sources in $srcdir" >&2
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
    { (exit 1); exit 1; }; }
   fi
 fi
@@ -730,8 +929,8 @@ ac_cv_env_CPP_value=$CPP
 if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
-  cat <<EOF
-\`configure' configures gc 6.1 to adapt to many kinds of systems.
+  cat <<_ACEOF
+\`configure' configures gc 6.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -751,9 +950,9 @@ Configuration:
   -n, --no-create         do not create output files
       --srcdir=DIR        find the sources in DIR [configure dir or \`..']
 
-EOF
+_ACEOF
 
-  cat <<EOF
+  cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
                           [$ac_default_prefix]
@@ -780,9 +979,9 @@ Fine tuning of the installation directories:
   --oldincludedir=DIR    C header files for non-gcc [/usr/include]
   --infodir=DIR          info documentation [PREFIX/info]
   --mandir=DIR           man documentation [PREFIX/man]
-EOF
+_ACEOF
 
-  cat <<\EOF
+  cat <<\_ACEOF
 
 Program names:
   --program-prefix=PREFIX            prepend PREFIX to installed program names
@@ -791,15 +990,16 @@ Program names:
 
 System types:
   --build=BUILD     configure for building on BUILD [guessed]
-  --host=HOST       build programs to run on HOST [BUILD]
-EOF
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
 fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of gc 6.1:";;
+     short | recursive ) echo "Configuration of gc 6.2:";;
    esac
-  cat <<\EOF
+  cat <<\_ACEOF
 
 Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
@@ -810,13 +1010,14 @@ Optional Features:
                           (and sometimes confusing) to the casual installer
   --enable-threads=TYPE   choose threading package
   --enable-parallel-mark       parallelize marking and free list construction
-  --enable-shared=PKGS  build shared libraries default=no
+  --enable-cplusplus           install C++ support
   --enable-shared=PKGS  build shared libraries default=yes
   --enable-static=PKGS  build static libraries default=yes
   --enable-fast-install=PKGS  optimize for fast installation default=yes
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --enable-full-debug  include full support for pointer backtracing etc.
   --enable-redirect-malloc  redirect malloc and friends to GC routines
+  --enable-gc-assertions  collector-internal assertion checking
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -842,41 +1043,61 @@ Some influential environment variables:
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <Hans_Boehm@hp.com>.
-EOF
+Report bugs to <Hans.Boehm@hp.com>.
+_ACEOF
 fi
 
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
   ac_popdir=`pwd`
-  for ac_subdir in : $ac_subdirs_all; do test "x$ac_subdir" = x: && continue
-    cd $ac_subdir
-    # A "../" for each directory in /$ac_subdir.
-    ac_dots=`echo $ac_subdir |
-             sed 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g'`
-
-    case $srcdir in
-    .) # No --srcdir option.  We are building in place.
-      ac_sub_srcdir=$srcdir ;;
-    [\\/]* | ?:[\\/]* ) # Absolute path.
-      ac_sub_srcdir=$srcdir/$ac_subdir ;;
-    *) # Relative path.
-      ac_sub_srcdir=$ac_dots$srcdir/$ac_subdir ;;
-    esac
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
 
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
     # Check for guested configure; otherwise get Cygnus style configure.
-    if test -f $ac_sub_srcdir/configure.gnu; then
+    if test -f $ac_srcdir/configure.gnu; then
       echo
-      $SHELL $ac_sub_srcdir/configure.gnu  --help=recursive
-    elif test -f $ac_sub_srcdir/configure; then
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
       echo
-      $SHELL $ac_sub_srcdir/configure  --help=recursive
-    elif test -f $ac_sub_srcdir/configure.ac ||
-           test -f $ac_sub_srcdir/configure.in; then
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
       echo
       $ac_configure --help
     else
-      echo "$as_me: WARNING: no configuration information is in $ac_subdir" >&2
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
     cd $ac_popdir
   done
@@ -884,33 +1105,33 @@ fi
 
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
-  cat <<\EOF
-gc configure 6.1
-generated by GNU Autoconf 2.52
+  cat <<\_ACEOF
+gc configure 6.2
+generated by GNU Autoconf 2.53
 
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
-EOF
+_ACEOF
   exit 0
 fi
 exec 5>config.log
-cat >&5 <<EOF
+cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by gc $as_me 6.1, which was
-generated by GNU Autoconf 2.52.  Invocation command line was
+It was created by gc $as_me 6.2, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
 
   $ $0 $@
 
-EOF
+_ACEOF
 {
 cat <<_ASUNAME
-## ---------- ##
-## Platform.  ##
-## ---------- ##
+## --------- ##
+## Platform. ##
+## --------- ##
 
 hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
 uname -m = `(uname -m) 2>/dev/null || echo unknown`
@@ -929,17 +1150,27 @@ hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
 /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
 
-PATH = $PATH
-
 _ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
 } >&5
 
-cat >&5 <<EOF
-## ------------ ##
-## Core tests.  ##
-## ------------ ##
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
 
-EOF
 
 # Keep a trace of the command line.
 # Strip out --no-create and --no-recursion so they do not pile up.
@@ -950,15 +1181,17 @@ for ac_arg
 do
   case $ac_arg in
   -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c) ;;
+  | --no-cr | --no-c | -n ) continue ;;
   -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    continue ;;
   *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"`
-    ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
-    ac_sep=" " ;;
-  *) ac_configure_args="$ac_configure_args$ac_sep$ac_arg"
-     ac_sep=" " ;;
+    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  case " $ac_configure_args " in
+    *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+    *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+       ac_sep=" " ;;
   esac
   # Get rid of the leading space.
 done
@@ -966,14 +1199,19 @@ done
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
 trap 'exit_status=$?
   # Save into config.log some information that might help in debugging.
-  echo >&5
-  echo "## ----------------- ##" >&5
-  echo "## Cache variables.  ##" >&5
-  echo "## ----------------- ##" >&5
-  echo >&5
-  # The following way of writing the cache mishandles newlines in values,
+  {
+    echo
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
 {
   (set) 2>&1 |
     case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
@@ -987,21 +1225,24 @@ trap 'exit_status=$?
         "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
     esac;
-} >&5
-  sed "/^$/d" confdefs.h >conftest.log
-  if test -s conftest.log; then
-    echo >&5
-    echo "## ------------ ##" >&5
-    echo "## confdefs.h.  ##" >&5
-    echo "## ------------ ##" >&5
-    echo >&5
-    cat conftest.log >&5
-  fi
-  (echo; echo) >&5
-  test "$ac_signal" != 0 &&
-    echo "$as_me: caught signal $ac_signal" >&5
-  echo "$as_me: exit $exit_status" >&5
-  rm -rf conftest* confdefs* core core.* *.core conf$$* $ac_clean_files &&
+}
+    echo
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
      ' 0
 for ac_signal in 1 2 13 15; do
@@ -1014,6 +1255,33 @@ rm -rf conftest* confdefs.h
 # AIX cpp loses on an empty file, so make sure it contains at least a newline.
 echo >confdefs.h
 
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
 # Let the site file select an alternate cache file if it wants to.
 # Prefer explicitly selected file to automatically selected ones.
 if test -z "$CONFIG_SITE"; then
@@ -1025,9 +1293,9 @@ if test -z "$CONFIG_SITE"; then
 fi
 for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
-    { echo "$as_me:1028: loading site script $ac_site_file" >&5
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
 echo "$as_me: loading site script $ac_site_file" >&6;}
-    cat "$ac_site_file" >&5
+    sed 's/^/| /' "$ac_site_file" >&5
     . "$ac_site_file"
   fi
 done
@@ -1036,7 +1304,7 @@ if test -r "$cache_file"; then
   # Some versions of bash will fail to source /dev/null (special
   # files actually), so we avoid doing that.
   if test -f "$cache_file"; then
-    { echo "$as_me:1039: loading cache $cache_file" >&5
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
 echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
       [\\/]* | ?:[\\/]* ) . $cache_file;;
@@ -1044,7 +1312,7 @@ echo "$as_me: loading cache $cache_file" >&6;}
     esac
   fi
 else
-  { echo "$as_me:1047: creating cache $cache_file" >&5
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
 echo "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
@@ -1060,42 +1328,42 @@ for ac_var in `(set) 2>&1 |
   eval ac_new_val="\$ac_env_${ac_var}_value"
   case $ac_old_set,$ac_new_set in
     set,)
-      { echo "$as_me:1063: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,set)
-      { echo "$as_me:1067: error: \`$ac_var' was not set in the previous run" >&5
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,);;
     *)
       if test "x$ac_old_val" != "x$ac_new_val"; then
-        { echo "$as_me:1073: error: \`$ac_var' has changed since the previous run:" >&5
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-        { echo "$as_me:1075:   former value:  $ac_old_val" >&5
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
 echo "$as_me:   former value:  $ac_old_val" >&2;}
-        { echo "$as_me:1077:   current value: $ac_new_val" >&5
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
 echo "$as_me:   current value: $ac_new_val" >&2;}
         ac_cache_corrupted=:
       fi;;
   esac
-  # Pass precious variables to config.status.  It doesn't matter if
-  # we pass some twice (in addition to the command line arguments).
+  # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
     *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"`
-      ac_configure_args="$ac_configure_args '$ac_arg'"
-      ;;
-    *) ac_configure_args="$ac_configure_args $ac_var=$ac_new_val"
-       ;;
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
     esac
   fi
 done
 if $ac_cache_corrupted; then
-  { echo "$as_me:1096: error: changes in the environment can compromise the build" >&5
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
 echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  { { echo "$as_me:1098: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
    { (exit 1); exit 1; }; }
 fi
@@ -1106,28 +1374,33 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='     ' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)      ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-echo "#! $SHELL" >conftest.sh
-echo  "exit 0"   >>conftest.sh
-chmod +x conftest.sh
-if { (echo "$as_me:1118: PATH=\".;.\"; conftest.sh") >&5
-  (PATH=".;."; conftest.sh) 2>&5
-  ac_status=$?
-  echo "$as_me:1121: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  ac_path_separator=';'
-else
-  ac_path_separator=:
-fi
-PATH_SEPARATOR="$ac_path_separator"
-rm -f conftest.sh
 
-am__api_version="1.6"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
+
 ac_aux_dir=
 for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
   if test -f $ac_dir/install-sh; then
@@ -1145,7 +1418,7 @@ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
   fi
 done
 if test -z "$ac_aux_dir"; then
-  { { echo "$as_me:1148: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
    { (exit 1); exit 1; }; }
 fi
@@ -1153,79 +1426,212 @@ ac_config_guess="$SHELL $ac_aux_dir/config.guess"
 ac_config_sub="$SHELL $ac_aux_dir/config.sub"
 ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 
-# Find a good install program.  We prefer a C program (faster),
-# so one script is as good as another.  But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo "$as_me:1168: checking for a BSD compatible install" >&5
-echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-    ac_save_IFS=$IFS; IFS=$ac_path_separator
-  for ac_dir in $PATH; do
-    IFS=$ac_save_IFS
-    # Account for people who put trailing slashes in PATH elements.
-    case $ac_dir/ in
-    / | ./ | .// | /cC/* \
-    | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \
-    | /usr/ucb/* ) ;;
-    *)
-      # OSF1 and SCO ODT 3.0 have their own names for install.
-      # Don't use installbsd from OSF since it installs stuff as root
-      # by default.
-      for ac_prog in ginstall scoinst install; do
-        if $as_executable_p "$ac_dir/$ac_prog"; then
-         if test $ac_prog = install &&
-            grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then
-           # AIX install.  It has an incompatible calling convention.
-           :
-         elif test $ac_prog = install &&
-           grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then
-           # program-specific install script used by HP pwplus--don't use.
-           :
-         else
-           ac_cv_path_install="$ac_dir/$ac_prog -c"
-           break 2
-         fi
-       fi
-      done
-      ;;
-    esac
-  done
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
 
 fi
-  if test "${ac_cv_path_install+set}" = set; then
-    INSTALL=$ac_cv_path_install
-  else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
-    # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
-    INSTALL=$ac_install_sh
-  fi
-fi
-echo "$as_me:1217: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+
+  echo "$as_me:$LINENO: checking GC version numbers" >&5
+echo $ECHO_N "checking GC version numbers... $ECHO_C" >&6
+  GC_VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([0-9][0-9]*\)[.].*$/\1/g'`
+  GC_VERSION_MINOR=`echo $PACKAGE_VERSION | sed 's/^[^.]*[.]\([0-9][0-9]*\).*$/\1/g'`
+  GC_ALPHA_VERSION=`echo $PACKAGE_VERSION | sed 's/^[^.]*[.][0-9]*//'`
+
+  case "$GC_ALPHA_VERSION" in
+    alpha*)
+      GC_ALPHA_VERSION=`echo $GC_ALPHA_VERSION \
+      | sed 's/alpha\([0-9][0-9]*\)/\1/'` ;;
+    *)  GC_ALPHA_MAJOR='' ;;
+  esac
+
+  if test :$GC_VERSION_MAJOR: = :: \
+     -o   :$GC_VERSION_MINOR: = :: ;
+  then
+    echo "$as_me:$LINENO: result: invalid" >&5
+echo "${ECHO_T}invalid" >&6
+    { { echo "$as_me:$LINENO: error: nonconforming PACKAGE_VERSION='$PACKAGE_VERSION'" >&5
+echo "$as_me: error: nonconforming PACKAGE_VERSION='$PACKAGE_VERSION'" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+
+  cat >>confdefs.h <<_ACEOF
+#define GC_VERSION_MAJOR $GC_VERSION_MAJOR
+_ACEOF
+
+  cat >>confdefs.h <<_ACEOF
+#define GC_VERSION_MINOR $GC_VERSION_MINOR
+_ACEOF
+
+  if test :$GC_ALPHA_VERSION: != :: ; then
+    cat >>confdefs.h <<_ACEOF
+#define GC_ALPHA_VERSION $GC_ALPHA_VERSION
+_ACEOF
+
+  fi
+  echo "$as_me:$LINENO: result: major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \
+${GC_ALPHA_VERSION:+alpha=}$GC_ALPHA_VERSION" >&5
+echo "${ECHO_T}major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \
+${GC_ALPHA_VERSION:+alpha=}$GC_ALPHA_VERSION" >&6
+
+am__api_version="1.6"
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
 test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-echo "$as_me:1228: checking whether build environment is sane" >&5
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
 # Just in case
 sleep 1
@@ -1249,7 +1655,7 @@ if (
       # if, for instance, CONFIG_SHELL is bash and it inherits a
       # broken ls alias from the environment.  This has actually
       # happened.  Such a system could not be considered "sane".
-      { { echo "$as_me:1252: error: ls -t appears to fail.  Make sure there is not a broken
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
 alias in your environment" >&5
 echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
 alias in your environment" >&2;}
@@ -1262,13 +1668,13 @@ then
    # Ok.
    :
 else
-   { { echo "$as_me:1265: error: newly created file is older than distributed files!
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
 Check your system clock" >&5
 echo "$as_me: error: newly created file is older than distributed files!
 Check your system clock" >&2;}
    { (exit 1); exit 1; }; }
 fi
-echo "$as_me:1271: result: yes" >&5
+echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
 test "$program_prefix" != NONE &&
   program_transform_name="s,^,$program_prefix,;$program_transform_name"
@@ -1283,6 +1689,7 @@ _ACEOF
 program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
 rm conftest.sed
 
+
 # expand $ac_aux_dir to an absolute path
 am_aux_dir=`cd $ac_aux_dir && pwd`
 
@@ -1292,15 +1699,15 @@ if eval "$MISSING --run true"; then
   am_missing_run="$MISSING --run "
 else
   am_missing_run=
-  { echo "$as_me:1295: WARNING: \`missing' script is too old or missing" >&5
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
 fi
 
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
 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 "$as_me:1303: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_AWK+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1308,41 +1715,44 @@ else
   if test -n "$AWK"; then
   ac_cv_prog_AWK="$AWK" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_AWK="$ac_prog"
-echo "$as_me:1318: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 AWK=$ac_cv_prog_AWK
 if test -n "$AWK"; then
-  echo "$as_me:1326: result: $AWK" >&5
+  echo "$as_me:$LINENO: result: $AWK" >&5
 echo "${ECHO_T}$AWK" >&6
 else
-  echo "$as_me:1329: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
   test -n "$AWK" && break
 done
 
-echo "$as_me:1336: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5
 echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
 if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.make <<\EOF
+  cat >conftest.make <<\_ACEOF
 all:
        @echo 'ac_maketemp="${MAKE}"'
-EOF
+_ACEOF
 # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
 eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
 if test -n "$ac_maketemp"; then
@@ -1353,11 +1763,11 @@ fi
 rm -f conftest.make
 fi
 if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
-  echo "$as_me:1356: result: yes" >&5
+  echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
   SET_MAKE=
 else
-  echo "$as_me:1360: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
   SET_MAKE="MAKE=${MAKE-make}"
 fi
@@ -1365,27 +1775,42 @@ fi
  # test to see if srcdir already configured
 if test "`cd $srcdir && pwd`" != "`pwd`" &&
    test -f $srcdir/config.status; then
-  { { echo "$as_me:1368: error: source directory already configured; run \"make distclean\" there first" >&5
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
 # Define the identity of the package.
  PACKAGE=gc
- VERSION=6.1
+ VERSION=6.2
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
 
 # Some tools Automake needs.
 
 ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
 
+
 AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
 
+
 AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
 
+
 AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
 
+
 MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
+
 AMTAR=${AMTAR-"${am_missing_run}tar"}
 
 install_sh=${install_sh-"$am_aux_dir/install-sh"}
@@ -1398,7 +1823,7 @@ if test "$cross_compiling" != no; then
   if test -n "$ac_tool_prefix"; then
   # 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 "$as_me:1401: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1406,25 +1831,28 @@ else
   if test -n "$STRIP"; then
   ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_STRIP="${ac_tool_prefix}strip"
-echo "$as_me:1416: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  echo "$as_me:1424: result: $STRIP" >&5
+  echo "$as_me:$LINENO: result: $STRIP" >&5
 echo "${ECHO_T}$STRIP" >&6
 else
-  echo "$as_me:1427: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1433,7 +1861,7 @@ if test -z "$ac_cv_prog_STRIP"; then
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-echo "$as_me:1436: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1441,15 +1869,18 @@ else
   if test -n "$ac_ct_STRIP"; then
   ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_STRIP="strip"
-echo "$as_me:1451: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
   test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
@@ -1457,10 +1888,10 @@ fi
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  echo "$as_me:1460: result: $ac_ct_STRIP" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
 echo "${ECHO_T}$ac_ct_STRIP" >&6
 else
-  echo "$as_me:1463: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1475,57 +1906,11 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
 
-# Make sure we can run config.sub.
-$ac_config_sub sun4 >/dev/null 2>&1 ||
-  { { echo "$as_me:1480: error: cannot run $ac_config_sub" >&5
-echo "$as_me: error: cannot run $ac_config_sub" >&2;}
-   { (exit 1); exit 1; }; }
 
-echo "$as_me:1484: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6
-if test "${ac_cv_build+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_build_alias=$build_alias
-test -z "$ac_cv_build_alias" &&
-  ac_cv_build_alias=`$ac_config_guess`
-test -z "$ac_cv_build_alias" &&
-  { { echo "$as_me:1493: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
-   { (exit 1); exit 1; }; }
-ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
-  { { echo "$as_me:1497: error: $ac_config_sub $ac_cv_build_alias failed." >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed." >&2;}
-   { (exit 1); exit 1; }; }
 
-fi
-echo "$as_me:1502: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6
-build=$ac_cv_build
-build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 
-echo "$as_me:1509: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6
-if test "${ac_cv_host+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_host_alias=$host_alias
-test -z "$ac_cv_host_alias" &&
-  ac_cv_host_alias=$ac_cv_build_alias
-ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
-  { { echo "$as_me:1518: error: $ac_config_sub $ac_cv_host_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
 
-fi
-echo "$as_me:1523: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6
-host=$ac_cv_host
-host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -1535,7 +1920,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:1538: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1543,25 +1928,28 @@ else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_CC="${ac_tool_prefix}gcc"
-echo "$as_me:1553: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:1561: result: $CC" >&5
+  echo "$as_me:$LINENO: result: $CC" >&5
 echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:1564: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1570,7 +1958,7 @@ if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-echo "$as_me:1573: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1578,25 +1966,28 @@ else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_CC="gcc"
-echo "$as_me:1588: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:1596: result: $ac_ct_CC" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
 echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:1599: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1609,7 +2000,7 @@ if test -z "$CC"; then
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:1612: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1617,25 +2008,28 @@ else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_CC="${ac_tool_prefix}cc"
-echo "$as_me:1627: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:1635: result: $CC" >&5
+  echo "$as_me:$LINENO: result: $CC" >&5
 echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:1638: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1644,7 +2038,7 @@ if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-echo "$as_me:1647: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1652,25 +2046,28 @@ else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_CC="cc"
-echo "$as_me:1662: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:1670: result: $ac_ct_CC" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
 echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:1673: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1683,7 +2080,7 @@ fi
 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 "$as_me:1686: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1692,19 +2089,22 @@ else
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
   ac_prog_rejected=no
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
-  ac_prog_rejected=yes
-  continue
-fi
-ac_cv_prog_CC="cc"
-echo "$as_me:1706: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 if test $ac_prog_rejected = yes; then
@@ -1716,7 +2116,7 @@ if test $ac_prog_rejected = yes; then
     # However, it has the same basename, so the bogon will be chosen
     # first if we set CC to just the basename; use the full file name.
     shift
-    set dummy "$ac_dir/$ac_word" ${1+"$@"}
+    set dummy "$as_dir/$ac_word" ${1+"$@"}
     shift
     ac_cv_prog_CC="$@"
   fi
@@ -1725,10 +2125,10 @@ fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:1728: result: $CC" >&5
+  echo "$as_me:$LINENO: result: $CC" >&5
 echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:1731: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1739,7 +2139,7 @@ if test -z "$CC"; then
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:1742: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1747,25 +2147,28 @@ else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-echo "$as_me:1757: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:1765: result: $CC" >&5
+  echo "$as_me:$LINENO: result: $CC" >&5
 echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:1768: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1778,7 +2181,7 @@ if test -z "$CC"; then
 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 "$as_me:1781: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1786,25 +2189,28 @@ else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_CC="$ac_prog"
-echo "$as_me:1796: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:1804: result: $ac_ct_CC" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
 echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:1807: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -1816,34 +2222,41 @@ fi
 
 fi
 
-test -z "$CC" && { { echo "$as_me:1819: error: no acceptable cc found in \$PATH" >&5
-echo "$as_me: error: no acceptable cc found in \$PATH" >&2;}
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;}
    { (exit 1); exit 1; }; }
 
 # Provide some information about the compiler.
-echo "$as_me:1824:" \
+echo "$as_me:$LINENO:" \
      "checking for C compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:1827: \"$ac_compiler --version </dev/null >&5\"") >&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
   (eval $ac_compiler --version </dev/null >&5) 2>&5
   ac_status=$?
-  echo "$as_me:1830: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:1832: \"$ac_compiler -v </dev/null >&5\"") >&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
   (eval $ac_compiler -v </dev/null >&5) 2>&5
   ac_status=$?
-  echo "$as_me:1835: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:1837: \"$ac_compiler -V </dev/null >&5\"") >&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
   (eval $ac_compiler -V </dev/null >&5) 2>&5
   ac_status=$?
-  echo "$as_me:1840: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
 
 cat >conftest.$ac_ext <<_ACEOF
-#line 1844 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -1857,22 +2270,26 @@ ac_clean_files="$ac_clean_files a.out a.exe"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-echo "$as_me:1860: checking for C compiler default output" >&5
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
 echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:1863: \"$ac_link_default\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
   (eval $ac_link_default) 2>&5
   ac_status=$?
-  echo "$as_me:1866: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
   # Find the output, starting from the most likely.  This scheme is
 # not robust to junk in `.', hence go to wildcards (a.*) only as a last
 # resort.
-for ac_file in `ls a.exe conftest.exe 2>/dev/null;
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null;
                 ls a.out conftest 2>/dev/null;
                 ls a.* conftest.* 2>/dev/null`; do
   case $ac_file in
-    *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;;
+    *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;;
     a.out ) # We found the default executable, but exeext='' is most
             # certainly right.
             break;;
@@ -1886,34 +2303,34 @@ done
 else
   echo "$as_me: failed program was:" >&5
 cat conftest.$ac_ext >&5
-{ { echo "$as_me:1889: error: C compiler cannot create executables" >&5
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5
 echo "$as_me: error: C compiler cannot create executables" >&2;}
    { (exit 77); exit 77; }; }
 fi
 
 ac_exeext=$ac_cv_exeext
-echo "$as_me:1895: result: $ac_file" >&5
+echo "$as_me:$LINENO: result: $ac_file" >&5
 echo "${ECHO_T}$ac_file" >&6
 
 # Check the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-echo "$as_me:1900: checking whether the C compiler works" >&5
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0
 # If not cross compiling, check that we can run a simple program.
 if test "$cross_compiling" != yes; then
   if { ac_try='./$ac_file'
-  { (eval echo "$as_me:1906: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:1909: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
     cross_compiling=no
   else
     if test "$cross_compiling" = maybe; then
        cross_compiling=yes
     else
-       { { echo "$as_me:1916: error: cannot run C compiled programs.
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
 If you meant to cross compile, use \`--host'." >&5
 echo "$as_me: error: cannot run C compiled programs.
 If you meant to cross compile, use \`--host'." >&2;}
@@ -1921,24 +2338,24 @@ If you meant to cross compile, use \`--host'." >&2;}
     fi
   fi
 fi
-echo "$as_me:1924: result: yes" >&5
+echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
 
 rm -f a.out a.exe conftest$ac_cv_exeext
 ac_clean_files=$ac_clean_files_save
 # Check the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-echo "$as_me:1931: checking whether we are cross compiling" >&5
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:1933: result: $cross_compiling" >&5
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
 echo "${ECHO_T}$cross_compiling" >&6
 
-echo "$as_me:1936: checking for executable suffix" >&5
-echo $ECHO_N "checking for executable suffix... $ECHO_C" >&6
-if { (eval echo "$as_me:1938: \"$ac_link\"") >&5
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:1941: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
   # If both `conftest.exe' and `conftest' are `present' (well, observable)
 # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
@@ -1954,27 +2371,33 @@ for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do
   esac
 done
 else
-  { { echo "$as_me:1957: error: cannot compute EXEEXT: cannot compile and link" >&5
-echo "$as_me: error: cannot compute EXEEXT: cannot compile and link" >&2;}
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
 rm -f conftest$ac_cv_exeext
-echo "$as_me:1963: result: $ac_cv_exeext" >&5
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
 echo "${ECHO_T}$ac_cv_exeext" >&6
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-echo "$as_me:1969: checking for object suffix" >&5
-echo $ECHO_N "checking for object suffix... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
 if test "${ac_cv_objext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 1975 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -1984,10 +2407,10 @@ main ()
 }
 _ACEOF
 rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:1987: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:1990: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
   for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
   case $ac_file in
@@ -1999,26 +2422,32 @@ done
 else
   echo "$as_me: failed program was:" >&5
 cat conftest.$ac_ext >&5
-{ { echo "$as_me:2002: error: cannot compute OBJEXT: cannot compile" >&5
-echo "$as_me: error: cannot compute OBJEXT: cannot compile" >&2;}
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-echo "$as_me:2009: result: $ac_cv_objext" >&5
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
 echo "${ECHO_T}$ac_cv_objext" >&6
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-echo "$as_me:2013: checking whether we are using the GNU C compiler" >&5
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
 if test "${ac_cv_c_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 2019 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2031,16 +2460,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2034: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2037: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2040: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2043: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_compiler_gnu=yes
 else
@@ -2052,21 +2481,27 @@ rm -f conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:2055: result: $ac_cv_c_compiler_gnu" >&5
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
 GCC=`test $ac_compiler_gnu = yes && echo yes`
 ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
 CFLAGS="-g"
-echo "$as_me:2061: checking whether $CC accepts -g" >&5
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
 if test "${ac_cv_prog_cc_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 2067 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2076,16 +2511,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2079: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2082: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2085: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2088: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_prog_cc_g=yes
 else
@@ -2095,7 +2530,7 @@ ac_cv_prog_cc_g=no
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:2098: result: $ac_cv_prog_cc_g" >&5
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
@@ -2122,16 +2557,16 @@ cat >conftest.$ac_ext <<_ACEOF
 #endif
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2125: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2128: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2131: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2134: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   for ac_declaration in \
    ''\
@@ -2143,10 +2578,16 @@ if { (eval echo "$as_me:2125: \"$ac_compile\"") >&5
    'void exit (int);'
 do
   cat >conftest.$ac_ext <<_ACEOF
-#line 2146 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 $ac_declaration
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2156,16 +2597,16 @@ exit (42);
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2159: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2162: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2165: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2168: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   :
 else
@@ -2175,9 +2616,15 @@ continue
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
   cat >conftest.$ac_ext <<_ACEOF
-#line 2178 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 $ac_declaration
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2187,16 +2634,16 @@ exit (42);
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2190: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2193: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2196: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2199: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   break
 else
@@ -2232,15 +2679,17 @@ else
 fi
 rmdir .deps 2>/dev/null
 
+
 ac_config_commands="$ac_config_commands depfiles"
 
+
 am_make=${MAKE-make}
 cat > confinc << 'END'
 doit:
        @echo done
 END
 # If we don't find an include directive, just comment out the code.
-echo "$as_me:2243: checking for style of include used by $am_make" >&5
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
 am__include="#"
 am__quote=
@@ -2267,7 +2716,8 @@ if test "$am__include" = "#"; then
    fi
 fi
 
-echo "$as_me:2270: result: $_am_result" >&5
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
 echo "${ECHO_T}$_am_result" >&6
 rm -f confinc confmf
 
@@ -2281,6 +2731,7 @@ if test "x$enable_dependency_tracking" != xno; then
   AMDEPBACKSLASH='\'
 fi
 
+
 if test "x$enable_dependency_tracking" != xno; then
   AMDEP_TRUE=
   AMDEP_FALSE='#'
@@ -2289,9 +2740,12 @@ else
   AMDEP_FALSE=
 fi
 
+
+
+
 depcc="$CC"   am_compiler_list=
 
-echo "$as_me:2294: checking dependency style of $depcc" >&5
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2353,10 +2807,11 @@ else
 fi
 
 fi
-echo "$as_me:2356: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
 
+
 ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2367,7 +2822,7 @@ if test -n "$ac_tool_prefix"; then
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:2370: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CXX+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2375,25 +2830,28 @@ else
   if test -n "$CXX"; then
   ac_cv_prog_CXX="$CXX" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
-echo "$as_me:2385: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 CXX=$ac_cv_prog_CXX
 if test -n "$CXX"; then
-  echo "$as_me:2393: result: $CXX" >&5
+  echo "$as_me:$LINENO: result: $CXX" >&5
 echo "${ECHO_T}$CXX" >&6
 else
-  echo "$as_me:2396: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -2406,7 +2864,7 @@ if test -z "$CXX"; then
 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 "$as_me:2409: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2414,25 +2872,28 @@ else
   if test -n "$ac_ct_CXX"; then
   ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_CXX="$ac_prog"
-echo "$as_me:2424: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
 if test -n "$ac_ct_CXX"; then
-  echo "$as_me:2432: result: $ac_ct_CXX" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
 echo "${ECHO_T}$ac_ct_CXX" >&6
 else
-  echo "$as_me:2435: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -2443,35 +2904,42 @@ test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
   CXX=$ac_ct_CXX
 fi
 
+
 # Provide some information about the compiler.
-echo "$as_me:2447:" \
+echo "$as_me:$LINENO:" \
      "checking for C++ compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:2450: \"$ac_compiler --version </dev/null >&5\"") >&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
   (eval $ac_compiler --version </dev/null >&5) 2>&5
   ac_status=$?
-  echo "$as_me:2453: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:2455: \"$ac_compiler -v </dev/null >&5\"") >&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
   (eval $ac_compiler -v </dev/null >&5) 2>&5
   ac_status=$?
-  echo "$as_me:2458: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:2460: \"$ac_compiler -V </dev/null >&5\"") >&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
   (eval $ac_compiler -V </dev/null >&5) 2>&5
   ac_status=$?
-  echo "$as_me:2463: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
 
-echo "$as_me:2466: checking whether we are using the GNU C++ compiler" >&5
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 2472 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2484,16 +2952,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2487: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2490: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2493: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2496: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_compiler_gnu=yes
 else
@@ -2505,21 +2973,27 @@ rm -f conftest.$ac_objext conftest.$ac_ext
 ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:2508: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
 GXX=`test $ac_compiler_gnu = yes && echo yes`
 ac_test_CXXFLAGS=${CXXFLAGS+set}
 ac_save_CXXFLAGS=$CXXFLAGS
 CXXFLAGS="-g"
-echo "$as_me:2514: checking whether $CXX accepts -g" >&5
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
 if test "${ac_cv_prog_cxx_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 2520 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2529,16 +3003,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2532: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2535: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2538: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2541: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_prog_cxx_g=yes
 else
@@ -2548,7 +3022,7 @@ ac_cv_prog_cxx_g=no
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:2551: result: $ac_cv_prog_cxx_g" >&5
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
 if test "$ac_test_CXXFLAGS" = set; then
   CXXFLAGS=$ac_save_CXXFLAGS
@@ -2575,10 +3049,16 @@ for ac_declaration in \
    'void exit (int);'
 do
   cat >conftest.$ac_ext <<_ACEOF
-#line 2578 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 $ac_declaration
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2588,16 +3068,16 @@ exit (42);
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2591: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2594: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2597: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2600: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   :
 else
@@ -2607,9 +3087,15 @@ continue
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
   cat >conftest.$ac_ext <<_ACEOF
-#line 2610 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 $ac_declaration
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -2619,16 +3105,16 @@ exit (42);
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:2622: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:2625: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:2628: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:2631: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   break
 else
@@ -2652,7 +3138,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 depcc="$CXX"  am_compiler_list=
 
-echo "$as_me:2655: checking dependency style of $depcc" >&5
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
 if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2714,20 +3200,23 @@ else
 fi
 
 fi
-echo "$as_me:2717: result: $am_cv_CXX_dependencies_compiler_type" >&5
+echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
 echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6
 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
 
+
+
 # By default we simply use the C compiler to build assembly code.
 
 : ${CCAS='$(CC)'}
 # Set ASFLAGS if not already set.
 : ${CCASFLAGS='$(CFLAGS)'}
 
+
 if test -n "$ac_tool_prefix"; then
   # 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 "$as_me:2730: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_AR+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2735,25 +3224,28 @@ else
   if test -n "$AR"; then
   ac_cv_prog_AR="$AR" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_AR="${ac_tool_prefix}ar"
-echo "$as_me:2745: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 AR=$ac_cv_prog_AR
 if test -n "$AR"; then
-  echo "$as_me:2753: result: $AR" >&5
+  echo "$as_me:$LINENO: result: $AR" >&5
 echo "${ECHO_T}$AR" >&6
 else
-  echo "$as_me:2756: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -2762,7 +3254,7 @@ if test -z "$ac_cv_prog_AR"; then
   ac_ct_AR=$AR
   # Extract the first word of "ar", so it can be a program name with args.
 set dummy ar; ac_word=$2
-echo "$as_me:2765: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2770,25 +3262,28 @@ else
   if test -n "$ac_ct_AR"; then
   ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_AR="ar"
-echo "$as_me:2780: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 ac_ct_AR=$ac_cv_prog_ac_ct_AR
 if test -n "$ac_ct_AR"; then
-  echo "$as_me:2788: result: $ac_ct_AR" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
 echo "${ECHO_T}$ac_ct_AR" >&6
 else
-  echo "$as_me:2791: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -2800,7 +3295,7 @@ fi
 if test -n "$ac_tool_prefix"; then
   # 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 "$as_me:2803: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_RANLIB+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2808,25 +3303,28 @@ else
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-echo "$as_me:2818: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 RANLIB=$ac_cv_prog_RANLIB
 if test -n "$RANLIB"; then
-  echo "$as_me:2826: result: $RANLIB" >&5
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
 echo "${ECHO_T}$RANLIB" >&6
 else
-  echo "$as_me:2829: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -2835,7 +3333,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
   ac_ct_RANLIB=$RANLIB
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
-echo "$as_me:2838: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -2843,15 +3341,18 @@ else
   if test -n "$ac_ct_RANLIB"; then
   ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_RANLIB="ranlib"
-echo "$as_me:2853: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
   test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
@@ -2859,10 +3360,10 @@ fi
 fi
 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
 if test -n "$ac_ct_RANLIB"; then
-  echo "$as_me:2862: result: $ac_ct_RANLIB" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
 echo "${ECHO_T}$ac_ct_RANLIB" >&6
 else
-  echo "$as_me:2865: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -2870,6 +3371,7 @@ fi
 else
   RANLIB="$ac_cv_prog_RANLIB"
 fi
+  # :)
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2883,43 +3385,48 @@ fi
 # AFS /usr/afsws/bin/install, which mishandles nonexistent args
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
-echo "$as_me:2886: checking for a BSD compatible install" >&5
-echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
 if test -z "$INSTALL"; then
 if test "${ac_cv_path_install+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-    ac_save_IFS=$IFS; IFS=$ac_path_separator
-  for ac_dir in $PATH; do
-    IFS=$ac_save_IFS
-    # Account for people who put trailing slashes in PATH elements.
-    case $ac_dir/ in
-    / | ./ | .// | /cC/* \
-    | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \
-    | /usr/ucb/* ) ;;
-    *)
-      # OSF1 and SCO ODT 3.0 have their own names for install.
-      # Don't use installbsd from OSF since it installs stuff as root
-      # by default.
-      for ac_prog in ginstall scoinst install; do
-        if $as_executable_p "$ac_dir/$ac_prog"; then
-         if test $ac_prog = install &&
-            grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then
-           # AIX install.  It has an incompatible calling convention.
-           :
-         elif test $ac_prog = install &&
-           grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then
-           # program-specific install script used by HP pwplus--don't use.
-           :
-         else
-           ac_cv_path_install="$ac_dir/$ac_prog -c"
-           break 2
-         fi
-       fi
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
       done
-      ;;
-    esac
-  done
+    done
+    ;;
+esac
+done
+
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
@@ -2932,7 +3439,7 @@ fi
     INSTALL=$ac_install_sh
   fi
 fi
-echo "$as_me:2935: result: $INSTALL" >&5
+echo "$as_me:$LINENO: result: $INSTALL" >&5
 echo "${ECHO_T}$INSTALL" >&6
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
@@ -2943,7 +3450,8 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-echo "$as_me:2946: checking whether to enable maintainer-specific portions of Makefiles" >&5
+
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
 echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
@@ -2952,9 +3460,10 @@ if test "${enable_maintainer_mode+set}" = set; then
 else
   USE_MAINTAINER_MODE=no
 fi;
-  echo "$as_me:2955: result: $USE_MAINTAINER_MODE" >&5
+  echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
 echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
 
+
 if test $USE_MAINTAINER_MODE = yes; then
   MAINTAINER_MODE_TRUE=
   MAINTAINER_MODE_FALSE='#'
@@ -2965,47 +3474,25 @@ fi
 
   MAINT=$MAINTAINER_MODE_TRUE
 
-if test "${srcdir}" = "."; then
-  if test "${with_target_subdir}" != "." -a -n "${with_target_subdir}"; then
-    gc_basedir="${srcdir}/${with_multisrctop}../$1"
-  else
-    gc_basedir="${srcdir}/${with_multisrctop}$1"
-  fi
-else
-  gc_basedir="${srcdir}/$1"
-fi
-
-# We need AC_EXEEXT to keep automake happy in cygnus mode.  However,
-# at least currently, we never actually build a program, so we never
-# need to use $(EXEEXT).  Moreover, the test for EXEEXT normally
-# fails, because we are probably configuring with a cross compiler
-# which can't create executables.  So we include AC_EXEEXT to keep
-# automake happy, but we don't execute it, since we don't care about
-# the result.
-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.
-  :
 
-fi
 
 . ${srcdir}/configure.host
 
 GC_CFLAGS=${gc_cflags}
 
+
 # Check whether --enable-threads or --disable-threads was given.
 if test "${enable_threads+set}" = set; then
   enableval="$enable_threads"
   THREADS=$enableval
 else
-   echo "$as_me:3002: checking for thread model used by GCC" >&5
+   echo "$as_me:$LINENO: checking for thread model used by GCC" >&5
 echo $ECHO_N "checking for thread model used by GCC... $ECHO_C" >&6
     THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
     if test -z "$THREADS"; then
       THREADS=no
     fi
-    echo "$as_me:3008: result: $THREADS" >&5
+    echo "$as_me:$LINENO: result: $THREADS" >&5
 echo "${ECHO_T}$THREADS" >&6
 fi;
 
@@ -3014,7 +3501,7 @@ if test "${enable_parallel_mark+set}" = set; then
   enableval="$enable_parallel_mark"
   case "$THREADS" in
       no | none | single)
-       { { echo "$as_me:3017: error: Parallel mark requires --enable-threads=x spec" >&5
+       { { echo "$as_me:$LINENO: error: Parallel mark requires --enable-threads=x spec" >&5
 echo "$as_me: error: Parallel mark requires --enable-threads=x spec" >&2;}
    { (exit 1); exit 1; }; }
        ;;
@@ -3022,6 +3509,12 @@ echo "$as_me: error: Parallel mark requires --enable-threads=x spec" >&2;}
 
 fi;
 
+# Check whether --enable-cplusplus or --disable-cplusplus was given.
+if test "${enable_cplusplus+set}" = set; then
+  enableval="$enable_cplusplus"
+
+fi;
+
 INCLUDES=-I${srcdir}/include
 THREADLIBS=
 case "$THREADS" in
@@ -3033,103 +3526,129 @@ case "$THREADS" in
     THREADLIBS=-lpthread
     case "$host" in
      x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_LINUX_THREADS 1
-EOF
+_ACEOF
 
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define _REENTRANT 1
-EOF
+_ACEOF
 
         if test "${enable_parallel_mark}" = yes; then
-         cat >>confdefs.h <<\EOF
+         cat >>confdefs.h <<\_ACEOF
 #define PARALLEL_MARK 1
-EOF
+_ACEOF
 
        fi
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define THREAD_LOCAL_ALLOC 1
-EOF
+_ACEOF
 
        ;;
      *-*-linux*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_LINUX_THREADS 1
-EOF
+_ACEOF
 
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define _REENTRANT 1
-EOF
+_ACEOF
+
+       ;;
+     *-*-aix*)
+       cat >>confdefs.h <<\_ACEOF
+#define GC_AIX_THREADS 1
+_ACEOF
+
+       cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
 
        ;;
      *-*-hpux*)
-       { echo "$as_me:3066: WARNING: \"Only HP/UX 11 threads are supported.\"" >&5
+       { echo "$as_me:$LINENO: WARNING: \"Only HP/UX 11 threads are supported.\"" >&5
 echo "$as_me: WARNING: \"Only HP/UX 11 threads are supported.\"" >&2;}
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_HPUX_THREADS 1
-EOF
+_ACEOF
 
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define _POSIX_C_SOURCE 199506L
-EOF
+_ACEOF
 
        if test "${enable_parallel_mark}" = yes; then
-         cat >>confdefs.h <<\EOF
+         cat >>confdefs.h <<\_ACEOF
 #define PARALLEL_MARK 1
-EOF
+_ACEOF
 
        fi
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define THREAD_LOCAL_ALLOC 1
-EOF
+_ACEOF
 
        THREADLIBS="-lpthread -lrt"
        ;;
      *-*-freebsd*)
-       { echo "$as_me:3089: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&5
+       { echo "$as_me:$LINENO: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&5
 echo "$as_me: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&2;}
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_FREEBSD_THREADS 1
-EOF
+_ACEOF
 
        INCLUDES="$INCLUDES -pthread"
        THREADLIBS=-pthread
        ;;
      *-*-solaris*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_SOLARIS_THREADS 1
-EOF
+_ACEOF
 
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_SOLARIS_PTHREADS 1
-EOF
+_ACEOF
 
        ;;
      *-*-irix*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_IRIX_THREADS 1
-EOF
+_ACEOF
 
        ;;
      *-*-cygwin*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_WIN32_THREADS 1
-EOF
+_ACEOF
+
+       ;;
+     *-*-darwin*)
+       cat >>confdefs.h <<\_ACEOF
+#define GC_DARWIN_THREADS 1
+_ACEOF
+
+       cat >>confdefs.h <<\_ACEOF
+#define THREAD_LOCAL_ALLOC 1
+_ACEOF
+
+       if test "${enable_parallel_mark}" = yes; then
+         cat >>confdefs.h <<\_ACEOF
+#define PARALLEL_MARK 1
+_ACEOF
 
+       fi
        ;;
      *-*-osf*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define GC_OSF1_THREADS 1
-EOF
+_ACEOF
 
         if test "${enable_parallel_mark}" = yes; then
-         cat >>confdefs.h <<\EOF
+         cat >>confdefs.h <<\_ACEOF
 #define PARALLEL_MARK 1
-EOF
+_ACEOF
 
-         cat >>confdefs.h <<\EOF
+         cat >>confdefs.h <<\_ACEOF
 #define THREAD_LOCAL_ALLOC 1
-EOF
+_ACEOF
 
          # May want to enable it in other cases, too.
          # Measurements havent yet been done.
@@ -3140,53 +3659,90 @@ EOF
     esac
     ;;
  win32)
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define GC_WIN32_THREADS 1
-EOF
+_ACEOF
 
-        cat >>confdefs.h <<\EOF
+        cat >>confdefs.h <<\_ACEOF
 #define NO_GETENV 1
-EOF
+_ACEOF
 
     ;;
  dgux386)
     THREADS=dgux386
+echo "$as_me:$LINENO: result: $THREADLIBS" >&5
+echo "${ECHO_T}$THREADLIBS" >&6
     # Use pthread GCC  switch
     THREADLIBS=-pthread
     if test "${enable_parallel_mark}" = yes; then
-        cat >>confdefs.h <<\EOF
+        cat >>confdefs.h <<\_ACEOF
 #define PARALLEL_MARK 1
-EOF
+_ACEOF
 
     fi
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define THREAD_LOCAL_ALLOC 1
-EOF
+_ACEOF
 
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define GC_DGUX386_THREADS 1
-EOF
+_ACEOF
 
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define DGUX_THREADS 1
-EOF
+_ACEOF
 
     # Enable _POSIX4A_DRAFT10_SOURCE with flag -pthread
     INCLUDES="-pthread $INCLUDES"
+    ;;
+ aix)
+    THREADS=posix
+    THREADLIBS=-lpthread
+    cat >>confdefs.h <<\_ACEOF
+#define GC_AIX_THREADS 1
+_ACEOF
+
+    cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
     ;;
  decosf1 | irix | mach | os2 | solaris | dce | vxworks)
-    { { echo "$as_me:3178: error: thread package $THREADS not yet supported" >&5
+    { { echo "$as_me:$LINENO: error: thread package $THREADS not yet supported" >&5
 echo "$as_me: error: thread package $THREADS not yet supported" >&2;}
    { (exit 1); exit 1; }; }
     ;;
  *)
-    { { echo "$as_me:3183: error: $THREADS is an unknown thread package" >&5
+    { { echo "$as_me:$LINENO: error: $THREADS is an unknown thread package" >&5
 echo "$as_me: error: $THREADS is an unknown thread package" >&2;}
    { (exit 1); exit 1; }; }
     ;;
 esac
 
-echo "$as_me:3189: 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 "$as_me:$LINENO: checking for dlopen in -ldl" >&5
 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
 if test "${ac_cv_lib_dl_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -3194,7 +3750,7 @@ else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
-#line 3197 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 /* Override any gcc2 internal prototype to avoid an error.  */
@@ -3204,6 +3760,12 @@ extern "C"
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
 char dlopen ();
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -3213,16 +3775,16 @@ dlopen ();
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:3216: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:3219: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:3222: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:3225: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_lib_dl_dlopen=yes
 else
@@ -3233,14 +3795,20 @@ fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:3236: result: $ac_cv_lib_dl_dlopen" >&5
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
 if test $ac_cv_lib_dl_dlopen = yes; then
   EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl"
 fi
 
+    ;;
+esac
+
+
+
 target_all=libgc.la
 
+
 TARGET_ECOS="no"
 
 # Check whether --with-ecos or --without-ecos was given.
@@ -3251,49 +3819,49 @@ if test "${with_ecos+set}" = set; then
 fi;
 
 addobjs=
+addlibs=
+addincludes=
+addtests=
 CXXINCLUDES=
 case "$TARGET_ECOS" in
    no)
       ;;
    *)
-      cat >>confdefs.h <<\EOF
+      cat >>confdefs.h <<\_ACEOF
 #define ECOS 1
-EOF
+_ACEOF
 
       CXXINCLUDES="-I${TARGET_ECOS}/include"
       addobjs="$addobjs ecos.lo"
       ;;
 esac
 
-machdep=
+if test "${enable_cplusplus}" = yes; then
+      addincludes="$addincludes include/gc_cpp.h include/gc_allocator.h"
+      addtests="$addtests test_cpp"
+fi
 
-case "$host" in
- alpha-*-openbsd*)
-     # Check whether --enable-shared or --disable-shared was given.
-if test "${enable_shared+set}" = set; then
-  enableval="$enable_shared"
-  p=${PACKAGE-default}
-case $enableval in
-yes) enable_shared=yes ;;
-no) enable_shared=no ;;
-*)
-  enable_shared=no
-  # Look at the argument we got.  We use all the common list separators.
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
-  for pkg in $enableval; do
-    if test "X$pkg" = "X$p"; then
-      enable_shared=yes
-    fi
-  done
-  IFS="$ac_save_ifs"
-  ;;
-esac
+
+
+if test "${enable_cplusplus}" = yes; then
+  CPLUSPLUS_TRUE=
+  CPLUSPLUS_FALSE='#'
 else
-  enable_shared=no
-fi;
-     ;;
- *)
-     # Check whether --enable-shared or --disable-shared was given.
+  CPLUSPLUS_TRUE='#'
+  CPLUSPLUS_FALSE=
+fi
+
+
+
+
+
+
+
+# Configuration of shared libraries
+#
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+# Check whether --enable-shared or --disable-shared was given.
 if test "${enable_shared+set}" = set; then
   enableval="$enable_shared"
   p=${PACKAGE-default}
@@ -3315,14 +3883,29 @@ esac
 else
   enable_shared=yes
 fi;
+
+case "$host" in
+ alpha-*-openbsd*)
+     enable_shared=no
+     echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+     ;;
+ *)
+     echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
      ;;
 esac
 
+# Configuration of machine-dependent code
+#
+echo "$as_me:$LINENO: checking which machine-dependent code should be used" >&5
+echo $ECHO_N "checking which machine-dependent code should be used... $ECHO_C" >&6
+machdep=
 case "$host" in
  alpha-*-openbsd*)
     machdep="alpha_mach_dep.lo"
     if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
-       { echo "$as_me:3325: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&5
+       { echo "$as_me:$LINENO: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&5
 echo "$as_me: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&2;}
     fi
     ;;
@@ -3330,20 +3913,20 @@ echo "$as_me: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is
     machdep="alpha_mach_dep.lo"
     ;;
  i?86-*-solaris2.[89]*)
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define SOLARIS25_PROC_VDB_BUG_FIXED 1
-EOF
+_ACEOF
 
     ;;
  mipstx39-*-elf*)
     machdep="mips_ultrix_mach_dep.lo"
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define STACKBASE __stackbase
-EOF
+_ACEOF
 
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define DATASTART_IS_ETEXT 1
-EOF
+_ACEOF
 
     ;;
  mips-dec-ultrix*)
@@ -3355,9 +3938,9 @@ EOF
     ;;
  mips-*-*)
     machdep="mips_sgi_mach_dep.lo"
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define NO_EXECUTE_PERMISSION 1
-EOF
+_ACEOF
 
     ;;
  sparc-*-netbsd*)
@@ -3365,9 +3948,9 @@ EOF
     ;;
  sparc-sun-solaris2.3*)
     machdep="sparc_mach_dep.lo"
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define SUNOS53_SHARED_LIB 1
-EOF
+_ACEOF
 
     ;;
  sparc-sun-solaris2.*)
@@ -3378,10 +3961,16 @@ EOF
     ;;
 esac
 if test x"$machdep" = x; then
+echo "$as_me:$LINENO: result: $machdep" >&5
+echo "${ECHO_T}$machdep" >&6
    machdep="mach_dep.lo"
 fi
 addobjs="$addobjs $machdep"
 
+
+
+
+
 # Check whether --enable-static or --disable-static was given.
 if test "${enable_static+set}" = set; then
   enableval="$enable_static"
@@ -3437,6 +4026,7 @@ if test "X${PATH_SEPARATOR+set}" != Xset; then
   PATH_SEPARATOR=$lt_cv_sys_path_separator
 fi
 
+
 # Check whether --with-gnu-ld or --without-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then
   withval="$with_gnu_ld"
@@ -3447,7 +4037,7 @@ fi;
 ac_prog=ld
 if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
-  echo "$as_me:3450: checking for ld used by GCC" >&5
+  echo "$as_me:$LINENO: checking for ld used by GCC" >&5
 echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
   case $host in
   *-*-mingw*)
@@ -3477,10 +4067,10 @@ echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
     ;;
   esac
 elif test "$with_gnu_ld" = yes; then
-  echo "$as_me:3480: checking for GNU ld" >&5
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
 echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
 else
-  echo "$as_me:3483: checking for non-GNU ld" >&5
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
 echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
 fi
 if test "${lt_cv_path_LD+set}" = set; then
@@ -3510,16 +4100,16 @@ fi
 
 LD="$lt_cv_path_LD"
 if test -n "$LD"; then
-  echo "$as_me:3513: result: $LD" >&5
+  echo "$as_me:$LINENO: result: $LD" >&5
 echo "${ECHO_T}$LD" >&6
 else
-  echo "$as_me:3516: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
-test -z "$LD" && { { echo "$as_me:3519: error: no acceptable ld found in \$PATH" >&5
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
    { (exit 1); exit 1; }; }
-echo "$as_me:3522: checking if the linker ($LD) is GNU ld" >&5
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
 echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
 if test "${lt_cv_prog_gnu_ld+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -3531,23 +4121,24 @@ else
   lt_cv_prog_gnu_ld=no
 fi
 fi
-echo "$as_me:3534: result: $lt_cv_prog_gnu_ld" >&5
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
 echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
 with_gnu_ld=$lt_cv_prog_gnu_ld
 
-echo "$as_me:3538: checking for $LD option to reload object files" >&5
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
 echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
 if test "${lt_cv_ld_reload_flag+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_cv_ld_reload_flag='-r'
 fi
-echo "$as_me:3545: result: $lt_cv_ld_reload_flag" >&5
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
 echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
 reload_flag=$lt_cv_ld_reload_flag
 test -n "$reload_flag" && reload_flag=" $reload_flag"
 
-echo "$as_me:3550: checking for BSD-compatible nm" >&5
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
 echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
 if test "${lt_cv_path_NM+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -3583,21 +4174,21 @@ fi
 fi
 
 NM="$lt_cv_path_NM"
-echo "$as_me:3586: result: $NM" >&5
+echo "$as_me:$LINENO: result: $NM" >&5
 echo "${ECHO_T}$NM" >&6
 
-echo "$as_me:3589: checking whether ln -s works" >&5
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
 LN_S=$as_ln_s
 if test "$LN_S" = "ln -s"; then
-  echo "$as_me:3593: result: yes" >&5
+  echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
 else
-  echo "$as_me:3596: result: no, using $LN_S" >&5
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
 echo "${ECHO_T}no, using $LN_S" >&6
 fi
 
-echo "$as_me:3600: checking how to recognise dependant libraries" >&5
+echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
 echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
 if test "${lt_cv_deplibs_check_method+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -3699,7 +4290,7 @@ irix5* | irix6*)
 # This must be Linux ELF.
 linux-gnu*)
   case $host_cpu in
-  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* )
     lt_cv_deplibs_check_method=pass_all ;;
   *)
     # glibc up to 2.1.1 does not perform some relocations on ARM
@@ -3775,13 +4366,19 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
 esac
 
 fi
-echo "$as_me:3778: result: $lt_cv_deplibs_check_method" >&5
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
 echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
 file_magic_cmd=$lt_cv_file_magic_cmd
 deplibs_check_method=$lt_cv_deplibs_check_method
 
+
+
+
+
+
+
 # Check for command to grab the raw symbol name followed by C symbol from nm.
-echo "$as_me:3784: checking command to parse $NM output" >&5
+echo "$as_me:$LINENO: checking command to parse $NM output" >&5
 echo $ECHO_N "checking command to parse $NM output... $ECHO_C" >&6
 if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -3862,17 +4459,17 @@ void nm_test_func(){}
 int main(){nm_test_var='a';nm_test_func();return(0);}
 EOF
 
-  if { (eval echo "$as_me:3865: \"$ac_compile\"") >&5
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:3868: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if { (eval echo "$as_me:3872: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+    if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
   (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
   ac_status=$?
-  echo "$as_me:3875: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
@@ -3924,10 +4521,10 @@ EOF
          save_CFLAGS="$CFLAGS"
          LIBS="conftstm.$ac_objext"
          CFLAGS="$CFLAGS$no_builtin_flag"
-         if { (eval echo "$as_me:3927: \"$ac_link\"") >&5
+         if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:3930: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && test -s conftest; then
            pipe_works=yes
          fi
@@ -3968,10 +4565,10 @@ else
 fi
 if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
 then
-  echo "$as_me:3971: result: failed" >&5
+  echo "$as_me:$LINENO: result: failed" >&5
 echo "${ECHO_T}failed" >&6
 else
-  echo "$as_me:3974: result: ok" >&5
+  echo "$as_me:$LINENO: result: ok" >&5
 echo "${ECHO_T}ok" >&6
 fi
 
@@ -3980,7 +4577,7 @@ ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:3983: checking how to run the C preprocessor" >&5
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
@@ -4001,18 +4598,18 @@ do
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat >conftest.$ac_ext <<_ACEOF
-#line 4004 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <assert.h>
                      Syntax error
 _ACEOF
-if { (eval echo "$as_me:4009: \"$ac_cpp conftest.$ac_ext\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   egrep -v '^ *\+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
-  echo "$as_me:4015: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } >/dev/null; then
   if test -s conftest.err; then
     ac_cpp_err=$ac_c_preproc_warn_flag
@@ -4035,17 +4632,17 @@ rm -f conftest.err conftest.$ac_ext
   # OK, works on sane cases.  Now check whether non-existent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
-#line 4038 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:4042: \"$ac_cpp conftest.$ac_ext\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   egrep -v '^ *\+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
-  echo "$as_me:4048: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } >/dev/null; then
   if test -s conftest.err; then
     ac_cpp_err=$ac_c_preproc_warn_flag
@@ -4082,7 +4679,7 @@ fi
 else
   ac_cv_prog_CPP=$CPP
 fi
-echo "$as_me:4085: result: $CPP" >&5
+echo "$as_me:$LINENO: result: $CPP" >&5
 echo "${ECHO_T}$CPP" >&6
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
@@ -4092,18 +4689,18 @@ do
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat >conftest.$ac_ext <<_ACEOF
-#line 4095 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <assert.h>
                      Syntax error
 _ACEOF
-if { (eval echo "$as_me:4100: \"$ac_cpp conftest.$ac_ext\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   egrep -v '^ *\+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
-  echo "$as_me:4106: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } >/dev/null; then
   if test -s conftest.err; then
     ac_cpp_err=$ac_c_preproc_warn_flag
@@ -4126,17 +4723,17 @@ rm -f conftest.err conftest.$ac_ext
   # OK, works on sane cases.  Now check whether non-existent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
-#line 4129 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:4133: \"$ac_cpp conftest.$ac_ext\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   egrep -v '^ *\+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
-  echo "$as_me:4139: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } >/dev/null; then
   if test -s conftest.err; then
     ac_cpp_err=$ac_c_preproc_warn_flag
@@ -4164,7 +4761,7 @@ rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then
   :
 else
-  { { echo "$as_me:4167: error: C preprocessor \"$CPP\" fails sanity check" >&5
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5
 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
    { (exit 1); exit 1; }; }
 fi
@@ -4175,26 +4772,28 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-for ac_header in dlfcn.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:4181: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 4187 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
-#include <$ac_header>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
 _ACEOF
-if { (eval echo "$as_me:4191: \"$ac_cpp conftest.$ac_ext\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   egrep -v '^ *\+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
-  echo "$as_me:4197: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } >/dev/null; then
   if test -s conftest.err; then
     ac_cpp_err=$ac_c_preproc_warn_flag
@@ -4205,71 +4804,337 @@ else
   ac_cpp_err=yes
 fi
 if test -z "$ac_cpp_err"; then
-  eval "$as_ac_Header=yes"
+  ac_cv_header_stdc=yes
 else
   echo "$as_me: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  eval "$as_ac_Header=no"
+  ac_cv_header_stdc=no
 fi
 rm -f conftest.err conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
 fi
-echo "$as_me:4216: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<EOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-EOF
+rm -f conftest*
 
 fi
-done
 
-# Only perform the check for file, if the check method requires it
-case $deplibs_check_method in
-file_magic*)
-  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
-    echo "$as_me:4230: checking for ${ac_tool_prefix}file" >&5
-echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
 else
-  case $MAGIC_CMD in
-  /*)
-  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
-  ;;
-  ?:/*)
-  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
-  ;;
-  *)
-  ac_save_MAGIC_CMD="$MAGIC_CMD"
-  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="/usr/bin:$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/${ac_tool_prefix}file; then
-      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
-      if test -n "$file_magic_test_file"; then
-       case $deplibs_check_method in
-       "file_magic "*)
-         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
-         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
-           egrep "$file_magic_regex" > /dev/null; then
-           :
-         else
-           cat <<EOF 1>&2
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
 
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such.  This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem.  Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
+fi
 
-EOF
-         fi ;;
-       esac
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="/usr/bin:$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           egrep "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
       fi
       break
     fi
@@ -4282,16 +5147,16 @@ fi
 
 MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
-  echo "$as_me:4285: result: $MAGIC_CMD" >&5
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
 echo "${ECHO_T}$MAGIC_CMD" >&6
 else
-  echo "$as_me:4288: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
 if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
-    echo "$as_me:4294: checking for file" >&5
+    echo "$as_me:$LINENO: checking for file" >&5
 echo $ECHO_N "checking for file... $ECHO_C" >&6
 if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4346,10 +5211,10 @@ fi
 
 MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
-  echo "$as_me:4349: result: $MAGIC_CMD" >&5
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
 echo "${ECHO_T}$MAGIC_CMD" >&6
 else
-  echo "$as_me:4352: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -4365,7 +5230,7 @@ esac
 if test -n "$ac_tool_prefix"; then
   # 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 "$as_me:4368: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_RANLIB+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4373,25 +5238,28 @@ else
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-echo "$as_me:4383: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 RANLIB=$ac_cv_prog_RANLIB
 if test -n "$RANLIB"; then
-  echo "$as_me:4391: result: $RANLIB" >&5
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
 echo "${ECHO_T}$RANLIB" >&6
 else
-  echo "$as_me:4394: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -4400,7 +5268,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
   ac_ct_RANLIB=$RANLIB
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
-echo "$as_me:4403: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4408,15 +5276,18 @@ else
   if test -n "$ac_ct_RANLIB"; then
   ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_RANLIB="ranlib"
-echo "$as_me:4418: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
   test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
@@ -4424,10 +5295,10 @@ fi
 fi
 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
 if test -n "$ac_ct_RANLIB"; then
-  echo "$as_me:4427: result: $ac_ct_RANLIB" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
 echo "${ECHO_T}$ac_ct_RANLIB" >&6
 else
-  echo "$as_me:4430: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -4439,7 +5310,7 @@ fi
 if test -n "$ac_tool_prefix"; then
   # 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 "$as_me:4442: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4447,25 +5318,28 @@ else
   if test -n "$STRIP"; then
   ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_STRIP="${ac_tool_prefix}strip"
-echo "$as_me:4457: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
 fi
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  echo "$as_me:4465: result: $STRIP" >&5
+  echo "$as_me:$LINENO: result: $STRIP" >&5
 echo "${ECHO_T}$STRIP" >&6
 else
-  echo "$as_me:4468: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -4474,7 +5348,7 @@ if test -z "$ac_cv_prog_STRIP"; then
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-echo "$as_me:4477: checking for $ac_word" >&5
+echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4482,15 +5356,18 @@ else
   if test -n "$ac_ct_STRIP"; then
   ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
 else
-  ac_save_IFS=$IFS; IFS=$ac_path_separator
-ac_dummy="$PATH"
-for ac_dir in $ac_dummy; do
-  IFS=$ac_save_IFS
-  test -z "$ac_dir" && ac_dir=.
-  $as_executable_p "$ac_dir/$ac_word" || continue
-ac_cv_prog_ac_ct_STRIP="strip"
-echo "$as_me:4492: found $ac_dir/$ac_word" >&5
-break
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
 done
 
   test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
@@ -4498,10 +5375,10 @@ fi
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  echo "$as_me:4501: result: $ac_ct_STRIP" >&5
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
 echo "${ECHO_T}$ac_ct_STRIP" >&6
 else
-  echo "$as_me:4504: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
@@ -4510,6 +5387,7 @@ else
   STRIP="$ac_cv_prog_STRIP"
 fi
 
+
 enable_dlopen=no
 enable_win32_dll=no
 
@@ -4525,11 +5403,11 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4528 "configure"' > conftest.$ac_ext
-  if { (eval echo "$as_me:4529: \"$ac_compile\"") >&5
+  echo '#line 5406 "configure"' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:4532: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
     case `/usr/bin/file conftest.$ac_objext` in
     *32-bit*)
@@ -4550,12 +5428,13 @@ case $host in
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
-  echo "$as_me:4553: checking whether the C compiler needs -belf" >&5
+  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
 echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
 if test "${lt_cv_cc_needs_belf+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
+
      ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4563,9 +5442,15 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
      cat >conftest.$ac_ext <<_ACEOF
-#line 4566 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -4575,16 +5460,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:4578: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:4581: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:4584: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:4587: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   lt_cv_cc_needs_belf=yes
 else
@@ -4600,7 +5485,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-echo "$as_me:4603: result: $lt_cv_cc_needs_belf" >&5
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
 echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
   if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
@@ -4608,6 +5493,7 @@ echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
   fi
   ;;
 
+
 esac
 
 # Sed substitution that helps us do robust quoting.  It backslashifies
@@ -4700,9 +5586,7 @@ fi
 set dummy $CC
 compiler="$2"
 
-## FIXME: this should be a separate macro
-##
-echo "$as_me:4705: checking for objdir" >&5
+echo "$as_me:$LINENO: checking for objdir" >&5
 echo $ECHO_N "checking for objdir... $ECHO_C" >&6
 rm -f .libs 2>/dev/null
 mkdir .libs 2>/dev/null
@@ -4713,13 +5597,10 @@ else
   objdir=_libs
 fi
 rmdir .libs 2>/dev/null
-echo "$as_me:4716: result: $objdir" >&5
+echo "$as_me:$LINENO: result: $objdir" >&5
 echo "${ECHO_T}$objdir" >&6
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
+
 
 # Check whether --with-pic or --without-pic was given.
 if test "${with_pic+set}" = set; then
@@ -4733,7 +5614,7 @@ test -z "$pic_mode" && pic_mode=default
 # We assume here that the value for lt_cv_prog_cc_pic will not be cached
 # in isolation, and that seeing it set (from the cache) indicates that
 # the associated values are set (in the cache) correctly too.
-echo "$as_me:4736: checking for $compiler option to produce PIC" >&5
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
 if test "${lt_cv_prog_cc_pic+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4880,14 +5761,14 @@ else
 fi
 
 if test -z "$lt_cv_prog_cc_pic"; then
-  echo "$as_me:4883: result: none" >&5
+  echo "$as_me:$LINENO: result: none" >&5
 echo "${ECHO_T}none" >&6
 else
-  echo "$as_me:4886: result: $lt_cv_prog_cc_pic" >&5
+  echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic" >&5
 echo "${ECHO_T}$lt_cv_prog_cc_pic" >&6
 
   # Check to make sure the pic_flag actually works.
-  echo "$as_me:4890: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
+  echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
 echo $ECHO_N "checking if $compiler PIC flag $lt_cv_prog_cc_pic works... $ECHO_C" >&6
   if test "${lt_cv_prog_cc_pic_works+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4895,9 +5776,15 @@ else
       save_CFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
     cat >conftest.$ac_ext <<_ACEOF
-#line 4898 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -4907,16 +5794,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:4910: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:4913: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:4916: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:4919: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
         case $host_os in
       hpux9* | hpux10* | hpux11*)
@@ -4945,6 +5832,7 @@ rm -f conftest.$ac_objext conftest.$ac_ext
 
 fi
 
+
   if test "X$lt_cv_prog_cc_pic_works" = Xno; then
     lt_cv_prog_cc_pic=
     lt_cv_prog_cc_can_build_shared=no
@@ -4952,27 +5840,23 @@ fi
     lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
   fi
 
-  echo "$as_me:4955: result: $lt_cv_prog_cc_pic_works" >&5
+  echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic_works" >&5
 echo "${ECHO_T}$lt_cv_prog_cc_pic_works" >&6
 fi
-##
-## END FIXME
 
 # Check for any special shared library compilation flags.
 if test -n "$lt_cv_prog_cc_shlib"; then
-  { echo "$as_me:4963: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5
+  { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5
 echo "$as_me: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&2;}
   if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$lt_cv_prog_cc_shlib[  ]" >/dev/null; then :
   else
-   { echo "$as_me:4967: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
+   { echo "$as_me:$LINENO: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
 echo "$as_me: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
     lt_cv_prog_cc_can_build_shared=no
   fi
 fi
 
-## FIXME: this should be a separate macro
-##
-echo "$as_me:4975: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
 echo $ECHO_N "checking if $compiler static flag $lt_cv_prog_cc_static works... $ECHO_C" >&6
 if test "${lt_cv_prog_cc_static_works+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -4981,9 +5865,15 @@ else
   save_LDFLAGS="$LDFLAGS"
   LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
   cat >conftest.$ac_ext <<_ACEOF
-#line 4984 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -4993,16 +5883,16 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:4996: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:4999: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:5002: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:5005: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   lt_cv_prog_cc_static_works=yes
 else
@@ -5014,9 +5904,10 @@ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 
 fi
 
+
 # Belt *and* braces to stop my trousers falling down:
 test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
-echo "$as_me:5019: result: $lt_cv_prog_cc_static_works" >&5
+echo "$as_me:$LINENO: result: $lt_cv_prog_cc_static_works" >&5
 echo "${ECHO_T}$lt_cv_prog_cc_static_works" >&6
 
 pic_flag="$lt_cv_prog_cc_pic"
@@ -5025,13 +5916,10 @@ wl="$lt_cv_prog_cc_wl"
 link_static_flag="$lt_cv_prog_cc_static"
 no_builtin_flag="$lt_cv_prog_cc_no_builtin"
 can_build_shared="$lt_cv_prog_cc_can_build_shared"
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
+
 # Check to see if options -o and -c are simultaneously supported by compiler
-echo "$as_me:5034: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
 if test "${lt_cv_compiler_c_o+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -5051,7 +5939,7 @@ chmod -w .
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
 compiler_c_o=no
-if { (eval echo configure:5054: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:5942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
   # The compiler can only warn and ignore the option if not recognized
   # So say no if there are warnings
   if test -s out/conftest.err; then
@@ -5075,12 +5963,12 @@ $rm -r conftest 2>/dev/null
 fi
 
 compiler_c_o=$lt_cv_compiler_c_o
-echo "$as_me:5078: result: $compiler_c_o" >&5
+echo "$as_me:$LINENO: result: $compiler_c_o" >&5
 echo "${ECHO_T}$compiler_c_o" >&6
 
 if test x"$compiler_c_o" = x"yes"; then
   # Check to see if we can write to a .lo
-  echo "$as_me:5083: checking if $compiler supports -c -o file.lo" >&5
+  echo "$as_me:$LINENO: checking if $compiler supports -c -o file.lo" >&5
 echo $ECHO_N "checking if $compiler supports -c -o file.lo... $ECHO_C" >&6
   if test "${lt_cv_compiler_o_lo+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -5092,9 +5980,15 @@ else
   save_objext="$ac_objext"
   ac_objext=lo
   cat >conftest.$ac_ext <<_ACEOF
-#line 5095 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -5104,16 +5998,16 @@ int some_variable = 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:5107: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:5110: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:5113: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:5116: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
       # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings
@@ -5134,21 +6028,17 @@ rm -f conftest.$ac_objext conftest.$ac_ext
 fi
 
   compiler_o_lo=$lt_cv_compiler_o_lo
-  echo "$as_me:5137: result: $compiler_o_lo" >&5
+  echo "$as_me:$LINENO: result: $compiler_o_lo" >&5
 echo "${ECHO_T}$compiler_o_lo" >&6
 else
   compiler_o_lo=no
 fi
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 # Check to see if we can do hard links to lock some files if needed
 hard_links="nottested"
 if test "$compiler_c_o" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
-  echo "$as_me:5151: checking if we can lock with hard links" >&5
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
   hard_links=yes
   $rm conftest*
@@ -5156,33 +6046,35 @@ echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  echo "$as_me:5159: result: $hard_links" >&5
+  echo "$as_me:$LINENO: result: $hard_links" >&5
 echo "${ECHO_T}$hard_links" >&6
   if test "$hard_links" = no; then
-    { echo "$as_me:5162: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
   need_locks=no
 fi
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 if test "$GCC" = yes; then
   # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
-  echo "$as_me:5176: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
 echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
   echo "int some_variable = 0;" > conftest.$ac_ext
   save_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
   compiler_rtti_exceptions=no
   cat >conftest.$ac_ext <<_ACEOF
-#line 5183 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -5192,16 +6084,16 @@ int some_variable = 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:5195: \"$ac_compile\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:5198: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:5201: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:5204: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
       # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings
@@ -5217,7 +6109,7 @@ cat conftest.$ac_ext >&5
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
   CFLAGS="$save_CFLAGS"
-  echo "$as_me:5220: result: $compiler_rtti_exceptions" >&5
+  echo "$as_me:$LINENO: result: $compiler_rtti_exceptions" >&5
 echo "${ECHO_T}$compiler_rtti_exceptions" >&6
 
   if test "$compiler_rtti_exceptions" = "yes"; then
@@ -5226,13 +6118,9 @@ echo "${ECHO_T}$compiler_rtti_exceptions" >&6
     no_builtin_flag=' -fno-builtin'
   fi
 fi
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 # See if the linker supports building shared libraries.
-echo "$as_me:5235: checking whether the linker ($LD) supports shared libraries" >&5
+echo "$as_me:$LINENO: checking whether the linker ($LD) supports shared libraries" >&5
 echo $ECHO_N "checking whether the linker ($LD) supports shared libraries... $ECHO_C" >&6
 
 allow_undefined_flag=
@@ -5912,16 +6800,12 @@ EOF
     ;;
   esac
 fi
-echo "$as_me:5915: result: $ld_shlibs" >&5
+echo "$as_me:$LINENO: result: $ld_shlibs" >&5
 echo "${ECHO_T}$ld_shlibs" >&6
 test "$ld_shlibs" = no && can_build_shared=no
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 # Check hardcoding attributes.
-echo "$as_me:5924: checking how to hardcode library paths into programs" >&5
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
 hardcode_action=
 if test -n "$hardcode_libdir_flag_spec" || \
@@ -5945,36 +6829,28 @@ else
   # directories.
   hardcode_action=unsupported
 fi
-echo "$as_me:5948: result: $hardcode_action" >&5
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
 echo "${ECHO_T}$hardcode_action" >&6
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 striplib=
 old_striplib=
-echo "$as_me:5957: checking whether stripping libraries is possible" >&5
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
 echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
 if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
   test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
   test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  echo "$as_me:5962: result: yes" >&5
+  echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
 else
-  echo "$as_me:5965: result: no" >&5
+  echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
-##
-## END FIXME
 
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 test -z "$deplibs_check_method" && deplibs_check_method=unknown
 
-## FIXME: this should be a separate macro
-##
 # PORTME Fill in your ld.so characteristics
-echo "$as_me:5977: checking dynamic linker characteristics" >&5
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
 library_names_spec=
 libname_spec='lib$name'
@@ -6367,25 +7243,17 @@ sysv4*MP*)
   dynamic_linker=no
   ;;
 esac
-echo "$as_me:6370: result: $dynamic_linker" >&5
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
 echo "${ECHO_T}$dynamic_linker" >&6
 test "$dynamic_linker" = no && can_build_shared=no
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 # Report the final consequences.
-echo "$as_me:6379: checking if libtool supports shared libraries" >&5
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
-echo "$as_me:6381: result: $can_build_shared" >&5
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
 echo "${ECHO_T}$can_build_shared" >&6
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
-echo "$as_me:6388: checking whether to build shared libraries" >&5
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
 echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
 test "$can_build_shared" = "no" && enable_shared=no
 
@@ -6406,21 +7274,15 @@ aix4*)
   fi
   ;;
 esac
-echo "$as_me:6409: result: $enable_shared" >&5
+echo "$as_me:$LINENO: result: $enable_shared" >&5
 echo "${ECHO_T}$enable_shared" >&6
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
-echo "$as_me:6416: checking whether to build static libraries" >&5
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
 echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
 # Make sure either enable_shared or enable_static is yes.
 test "$enable_shared" = yes || enable_static=yes
-echo "$as_me:6420: result: $enable_static" >&5
+echo "$as_me:$LINENO: result: $enable_static" >&5
 echo "${ECHO_T}$enable_static" >&6
-##
-## END FIXME
 
 if test "$hardcode_action" = relink; then
   # Fast installation is not supported
@@ -6457,13 +7319,13 @@ else
    ;;
 
   *)
-    echo "$as_me:6460: checking for shl_load" >&5
+    echo "$as_me:$LINENO: checking for shl_load" >&5
 echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
 if test "${ac_cv_func_shl_load+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 6466 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char shl_load (); below.  */
@@ -6477,6 +7339,12 @@ extern "C"
 char shl_load ();
 char (*f) ();
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -6494,16 +7362,16 @@ f = shl_load;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:6497: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6500: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:6503: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:6506: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_func_shl_load=yes
 else
@@ -6513,12 +7381,12 @@ ac_cv_func_shl_load=no
 fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 fi
-echo "$as_me:6516: result: $ac_cv_func_shl_load" >&5
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
 echo "${ECHO_T}$ac_cv_func_shl_load" >&6
 if test $ac_cv_func_shl_load = yes; then
   lt_cv_dlopen="shl_load"
 else
-  echo "$as_me:6521: checking for shl_load in -ldld" >&5
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
 if test "${ac_cv_lib_dld_shl_load+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6526,7 +7394,7 @@ else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldld  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
-#line 6529 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 /* Override any gcc2 internal prototype to avoid an error.  */
@@ -6536,6 +7404,12 @@ extern "C"
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
 char shl_load ();
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -6545,16 +7419,16 @@ shl_load ();
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:6548: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6551: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:6554: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:6557: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_lib_dld_shl_load=yes
 else
@@ -6565,18 +7439,18 @@ fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:6568: result: $ac_cv_lib_dld_shl_load" >&5
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
 if test $ac_cv_lib_dld_shl_load = yes; then
   lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
 else
-  echo "$as_me:6573: checking for dlopen" >&5
+  echo "$as_me:$LINENO: checking for dlopen" >&5
 echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
 if test "${ac_cv_func_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line 6579 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char dlopen (); below.  */
@@ -6590,6 +7464,12 @@ extern "C"
 char dlopen ();
 char (*f) ();
 
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -6607,16 +7487,16 @@ f = dlopen;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:6610: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6613: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:6616: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:6619: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_func_dlopen=yes
 else
@@ -6626,12 +7506,12 @@ ac_cv_func_dlopen=no
 fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 fi
-echo "$as_me:6629: result: $ac_cv_func_dlopen" >&5
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
 echo "${ECHO_T}$ac_cv_func_dlopen" >&6
 if test $ac_cv_func_dlopen = yes; then
   lt_cv_dlopen="dlopen"
 else
-  echo "$as_me:6634: checking for dlopen in -ldl" >&5
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
 if test "${ac_cv_lib_dl_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6639,7 +7519,7 @@ else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
-#line 6642 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 /* Override any gcc2 internal prototype to avoid an error.  */
@@ -6649,6 +7529,12 @@ extern "C"
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
 char dlopen ();
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -6658,16 +7544,16 @@ dlopen ();
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:6661: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6664: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:6667: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:6670: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_lib_dl_dlopen=yes
 else
@@ -6678,12 +7564,12 @@ fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:6681: result: $ac_cv_lib_dl_dlopen" >&5
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
 if test $ac_cv_lib_dl_dlopen = yes; then
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
-  echo "$as_me:6686: checking for dlopen in -lsvld" >&5
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
 echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
 if test "${ac_cv_lib_svld_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6691,7 +7577,7 @@ else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsvld  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
-#line 6694 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 /* Override any gcc2 internal prototype to avoid an error.  */
@@ -6701,6 +7587,12 @@ extern "C"
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
 char dlopen ();
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -6710,16 +7602,16 @@ dlopen ();
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:6713: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6716: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:6719: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:6722: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_lib_svld_dlopen=yes
 else
@@ -6730,12 +7622,12 @@ fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:6733: result: $ac_cv_lib_svld_dlopen" >&5
+echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
 echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
 if test $ac_cv_lib_svld_dlopen = yes; then
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
 else
-  echo "$as_me:6738: checking for dld_link in -ldld" >&5
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
 echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
 if test "${ac_cv_lib_dld_dld_link+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6743,7 +7635,7 @@ else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldld  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
-#line 6746 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 /* Override any gcc2 internal prototype to avoid an error.  */
@@ -6753,6 +7645,12 @@ extern "C"
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
 char dld_link ();
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
 int
 main ()
 {
@@ -6762,16 +7660,16 @@ dld_link ();
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:6765: \"$ac_link\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6768: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
          { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:6771: \"$ac_try\"") >&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  echo "$as_me:6774: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_lib_dld_dld_link=yes
 else
@@ -6782,20 +7680,25 @@ fi
 rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:6785: result: $ac_cv_lib_dld_dld_link" >&5
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
 echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
 if test $ac_cv_lib_dld_dld_link = yes; then
   lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
 fi
 
+
 fi
 
+
 fi
 
+
 fi
 
+
 fi
 
+
 fi
 
     ;;
@@ -6818,7 +7721,7 @@ fi
     save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
-    echo "$as_me:6821: checking whether a program can dlopen itself" >&5
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
 echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
 if test "${lt_cv_dlopen_self+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6829,7 +7732,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 6832 "configure"
+#line 7735 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -6890,10 +7793,10 @@ int main ()
     exit (status);
 }
 EOF
-  if { (eval echo "$as_me:6893: \"$ac_link\"") >&5
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6896: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) 2>/dev/null
     lt_status=$?
@@ -6909,13 +7812,14 @@ EOF
 fi
 rm -fr conftest*
 
+
 fi
-echo "$as_me:6913: result: $lt_cv_dlopen_self" >&5
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
 echo "${ECHO_T}$lt_cv_dlopen_self" >&6
 
     if test "x$lt_cv_dlopen_self" = xyes; then
       LDFLAGS="$LDFLAGS $link_static_flag"
-      echo "$as_me:6918: checking whether a statically linked program can dlopen itself" >&5
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
 echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
 if test "${lt_cv_dlopen_self_static+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6926,7 +7830,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 6929 "configure"
+#line 7833 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -6987,10 +7891,10 @@ int main ()
     exit (status);
 }
 EOF
-  if { (eval echo "$as_me:6990: \"$ac_link\"") >&5
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  echo "$as_me:6993: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) 2>/dev/null
     lt_status=$?
@@ -7006,8 +7910,9 @@ EOF
 fi
 rm -fr conftest*
 
+
 fi
-echo "$as_me:7010: result: $lt_cv_dlopen_self_static" >&5
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
 echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
     fi
 
@@ -7028,8 +7933,7 @@ echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
   esac
 fi
 
-## FIXME: this should be a separate macro
-##
+
 if test "$enable_shared" = yes && test "$GCC" = yes; then
   case $archive_cmds in
   *'~'*)
@@ -7039,7 +7943,7 @@ if test "$enable_shared" = yes && test "$GCC" = yes; then
     # Test whether the compiler implicitly links with -lc since on some
     # systems, -lgcc has to come before -lc. If gcc already passes -lc
     # to ld, don't add -lc before -lgcc.
-    echo "$as_me:7042: checking whether -lc should be explicitly linked in" >&5
+    echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
     if test "${lt_cv_archive_cmds_need_lc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -7047,10 +7951,10 @@ else
   $rm conftest*
     echo 'static int dummy;' > conftest.$ac_ext
 
-    if { (eval echo "$as_me:7050: \"$ac_compile\"") >&5
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  echo "$as_me:7053: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
       soname=conftest
       lib=conftest
@@ -7064,10 +7968,10 @@ else
       libname=conftest
       save_allow_undefined_flag=$allow_undefined_flag
       allow_undefined_flag=
-      if { (eval echo "$as_me:7067: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+      if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
   (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
   ac_status=$?
-  echo "$as_me:7070: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
       then
        lt_cv_archive_cmds_need_lc=no
@@ -7080,17 +7984,13 @@ else
     fi
 fi
 
-    echo "$as_me:7083: result: $lt_cv_archive_cmds_need_lc" >&5
+    echo "$as_me:$LINENO: result: $lt_cv_archive_cmds_need_lc" >&5
 echo "${ECHO_T}$lt_cv_archive_cmds_need_lc" >&6
     ;;
   esac
 fi
 need_lc=${lt_cv_archive_cmds_need_lc-yes}
-##
-## END FIXME
 
-## FIXME: this should be a separate macro
-##
 # The second clause should only fire when bootstrapping the
 # libtool distribution, otherwise you forgot to ship ltmain.sh
 # with your package, and you will get complaints that there are
@@ -7640,8 +8540,10 @@ EOF
     (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
   chmod +x "$ofile"
 fi
-##
-## END FIXME
+
+
+
+
 
 # This can be used to rebuild libtool when needed
 LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
@@ -7651,26 +8553,69 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 
 # Prevent multiple expansion
 
-echo "$as_me:7654: checking if host is AViiON running DGUX" >&5
+
+
+#
+# Check for AViiON Machines running DGUX
+#
+echo "$as_me:$LINENO: checking if host is AViiON running DGUX" >&5
 echo $ECHO_N "checking if host is AViiON running DGUX... $ECHO_C" >&6
 ac_is_dgux=no
-echo "$as_me:7657: checking for sys/dg_sys_info.h" >&5
+if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5
 echo $ECHO_N "checking for sys/dg_sys_info.h... $ECHO_C" >&6
 if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_dg_sys_info_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_dg_sys_info_h" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-#line 7663 "configure"
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/dg_sys_info.h usability" >&5
+echo $ECHO_N "checking sys/dg_sys_info.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+$ac_includes_default
+#include <sys/dg_sys_info.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/dg_sys_info.h presence" >&5
+echo $ECHO_N "checking sys/dg_sys_info.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
 #include "confdefs.h"
 #include <sys/dg_sys_info.h>
 _ACEOF
-if { (eval echo "$as_me:7667: \"$ac_cpp conftest.$ac_ext\"") >&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   egrep -v '^ *\+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
-  echo "$as_me:7673: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } >/dev/null; then
   if test -s conftest.err; then
     ac_cpp_err=$ac_c_preproc_warn_flag
@@ -7681,31 +8626,64 @@ else
   ac_cpp_err=yes
 fi
 if test -z "$ac_cpp_err"; then
-  ac_cv_header_sys_dg_sys_info_h=yes
+  ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  ac_cv_header_sys_dg_sys_info_h=no
+  ac_header_preproc=no
 fi
 rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};;
+esac
+echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5
+echo $ECHO_N "checking for sys/dg_sys_info.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_dg_sys_info_h=$ac_header_preproc
 fi
-echo "$as_me:7692: result: $ac_cv_header_sys_dg_sys_info_h" >&5
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_dg_sys_info_h" >&5
 echo "${ECHO_T}$ac_cv_header_sys_dg_sys_info_h" >&6
+
+fi
 if test $ac_cv_header_sys_dg_sys_info_h = yes; then
   ac_is_dgux=yes;
 fi
 
+
+
+echo "$as_me:$LINENO: result: $ac_is_dgux" >&5
+echo "${ECHO_T}$ac_is_dgux" >&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
+    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
+    else
       CFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
       CXXFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
-   fi
+    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"
@@ -7718,28 +8696,6 @@ if test "${with_cross_host+set}" = set; then
 
 fi;
 
-echo "$as_me:7721: checking whether to enable maintainer-specific portions of Makefiles" >&5
-echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
-    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then
-  enableval="$enable_maintainer_mode"
-  USE_MAINTAINER_MODE=$enableval
-else
-  USE_MAINTAINER_MODE=no
-fi;
-  echo "$as_me:7730: result: $USE_MAINTAINER_MODE" >&5
-echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
-
-if test $USE_MAINTAINER_MODE = yes; then
-  MAINTAINER_MODE_TRUE=
-  MAINTAINER_MODE_FALSE='#'
-else
-  MAINTAINER_MODE_TRUE='#'
-  MAINTAINER_MODE_FALSE=
-fi
-
-  MAINT=$MAINTAINER_MODE_TRUE
-
 # 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.
@@ -7751,12 +8707,13 @@ if false; then
 
 fi
 
-echo "$as_me:7754: checking for threads package to use" >&5
-echo $ECHO_N "checking for threads package to use... $ECHO_C" >&6
-
+echo "$as_me:$LINENO: checking whether Solaris gcc optimization fix is necessary" >&5
+echo $ECHO_N "checking whether Solaris gcc optimization fix is necessary... $ECHO_C" >&6
 case "$host" in
  sparc-sun-solaris2*)
     if test "$GCC" = yes; then
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
        new_CFLAGS=
        for i in $CFLAGS; do
          case "$i" in
@@ -7768,56 +8725,64 @@ case "$host" in
          esac
        done
        CFLAGS="$new_CFLAGS"
+    else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
     fi
     ;;
+ *) echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6 ;;
 esac
 
 MY_CFLAGS="$CFLAGS"
 
-cat >>confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
 #define SILENT 1
-EOF
+_ACEOF
 
-cat >>confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
 #define NO_SIGNALS 1
-EOF
+_ACEOF
 
-cat >>confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
 #define NO_EXECUTE_PERMISSION 1
-EOF
+_ACEOF
 
-cat >>confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
 #define ALL_INTERIOR_POINTERS 1
-EOF
+_ACEOF
 
-cat >>confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
 #define JAVA_FINALIZATION 1
-EOF
+_ACEOF
 
-cat >>confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
 #define GC_GCJ_SUPPORT 1
-EOF
+_ACEOF
 
-cat >>confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
 #define ATOMIC_UNCOLLECTABLE 1
-EOF
+_ACEOF
+
 
 if test -n "${with_cross_host}"; then
-   cat >>confdefs.h <<\EOF
+   cat >>confdefs.h <<\_ACEOF
 #define NO_SIGSET 1
-EOF
+_ACEOF
 
-   cat >>confdefs.h <<\EOF
+   cat >>confdefs.h <<\_ACEOF
 #define NO_CLOCK 1
-EOF
+_ACEOF
 
-   cat >>confdefs.h <<\EOF
+   cat >>confdefs.h <<\_ACEOF
 #define SMALL_CONFIG 1
-EOF
+_ACEOF
 
-   cat >>confdefs.h <<\EOF
+   cat >>confdefs.h <<\_ACEOF
 #define NO_DEBUGGING 1
-EOF
+_ACEOF
 
 fi
 
@@ -7825,39 +8790,39 @@ fi
 if test "${enable_full_debug+set}" = set; then
   enableval="$enable_full_debug"
    if test "$enable_full_debug" = "yes"; then
-    { echo "$as_me:7828: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&5
+    { echo "$as_me:$LINENO: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&5
 echo "$as_me: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&2;}
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define KEEP_BACK_PTRS 1
-EOF
+_ACEOF
 
-    cat >>confdefs.h <<\EOF
+    cat >>confdefs.h <<\_ACEOF
 #define DBG_HDRS_ALL 1
-EOF
+_ACEOF
 
     case $host in
       ia64-*-linux* )
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define MAKE_BACK_GRAPH 1
-EOF
+_ACEOF
 
       ;;
       x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define MAKE_BACK_GRAPH 1
-EOF
+_ACEOF
 
-       { echo "$as_me:7850: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&5
+       { echo "$as_me:$LINENO: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&5
 echo "$as_me: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&2;}
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define SAVE_CALL_COUNT 8
-EOF
+_ACEOF
 
       ;;
       i345686-*-dgux*)
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define MAKE_BACK_GRAPH 1
-EOF
+_ACEOF
 
       ;;
     esac
@@ -7872,26 +8837,40 @@ fi;
 
 if test "${enable_redirect_malloc}" = yes; then
     if test "${enable_full_debug}" = yes; then
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define REDIRECT_MALLOC GC_debug_malloc_replacement
-EOF
+_ACEOF
 
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define REDIRECT_REALLOC GC_debug_realloc_replacement
-EOF
+_ACEOF
 
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define REDIRECT_FREE GC_debug_free
-EOF
+_ACEOF
 
     else
-       cat >>confdefs.h <<\EOF
+       cat >>confdefs.h <<\_ACEOF
 #define REDIRECT_MALLOC GC_malloc
-EOF
+_ACEOF
 
     fi
 fi
 
+# Check whether --enable-gc-assertions or --disable-gc-assertions was given.
+if test "${enable_gc_assertions+set}" = set; then
+  enableval="$enable_gc_assertions"
+
+fi;
+if test "${enable_gc_assertions}" = yes; then
+    cat >>confdefs.h <<\_ACEOF
+#define GC_ASSERTIONS 1
+_ACEOF
+
+fi
+
+
+
 if test -z "$with_cross_host"; then
   USE_LIBDIR_TRUE=
   USE_LIBDIR_FALSE='#'
@@ -7900,13 +8879,8 @@ else
   USE_LIBDIR_FALSE=
 fi
 
-if test "${multilib}" = "yes"; then
-  multilib_arg="--enable-multilib"
-else
-  multilib_arg=
-fi
 
-ac_config_files="$ac_config_files Makefile"
+ac_config_files="$ac_config_files Makefile doc/Makefile include/Makefile"
 ac_config_commands="$ac_config_commands default"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -7989,7 +8963,7 @@ fi
 # If the first sed substitution is executed (which looks for macros that
 # take arguments), then we branch to the quote section.  Otherwise,
 # look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\EOF
+cat >confdef2opt.sed <<\_ACEOF
 t clear
 : clear
 s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
@@ -8003,7 +8977,7 @@ s,\[,\\&,g
 s,\],\\&,g
 s,\$,$$,g
 p
-EOF
+_ACEOF
 # We use echo to avoid assuming a particular line-breaking character.
 # The extra dot is to prevent the shell from consuming trailing
 # line-breaks from the sub-command output.  A line-break within
@@ -8014,29 +8988,37 @@ ac_LF_and_DOT=`echo; echo .`
 DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
 rm -f confdef2opt.sed
 
+
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
-  { { echo "$as_me:8018: error: conditional \"AMDEP\" was never defined.
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
 echo "$as_me: error: conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
-  { { echo "$as_me:8025: error: conditional \"MAINTAINER_MODE\" was never defined.
+  { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
 echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
-if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
-  { { echo "$as_me:8032: error: conditional \"MAINTAINER_MODE\" was never defined.
+if test -z "${POWERPC_DARWIN_TRUE}" && test -z "${POWERPC_DARWIN_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"POWERPC_DARWIN\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+echo "$as_me: error: conditional \"POWERPC_DARWIN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${CPLUSPLUS_TRUE}" && test -z "${CPLUSPLUS_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"CPLUSPLUS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"CPLUSPLUS\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
 if test -z "${USE_LIBDIR_TRUE}" && test -z "${USE_LIBDIR_FALSE}"; then
-  { { echo "$as_me:8039: error: conditional \"USE_LIBDIR\" was never defined.
+  { { echo "$as_me:$LINENO: error: conditional \"USE_LIBDIR\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
 echo "$as_me: error: conditional \"USE_LIBDIR\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
@@ -8046,22 +9028,25 @@ fi
 : ${CONFIG_STATUS=./config.status}
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:8049: creating $CONFIG_STATUS" >&5
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
 echo "$as_me: creating $CONFIG_STATUS" >&6;}
 cat >$CONFIG_STATUS <<_ACEOF
 #! $SHELL
-# Generated automatically by configure.
+# Generated by $as_me.
 # Run this file to recreate the current configuration.
 # Compiler output produced by configure, useful for debugging
 # configure, is in config.log if it exists.
 
 debug=false
 SHELL=\${CONFIG_SHELL-$SHELL}
-ac_cs_invocation="\$0 \$@"
-
 _ACEOF
 
 cat >>$CONFIG_STATUS <<\_ACEOF
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
 # Be Bourne compatible
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
@@ -8070,8 +9055,167 @@ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
   set -o posix
 fi
 
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
 # Name of the executable.
-as_me=`echo "$0" |sed 's,.*[\\/],,'`
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
 
 if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
@@ -8099,22 +9243,12 @@ rm -f conf$$ conf$$.exe conf$$.file
 
 as_executable_p="test -f"
 
-# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
-fi
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
 
-# NLS nuisances.
-$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; }
-$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; }
-$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; }
-$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; }
-$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; }
-$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; }
-$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; }
-$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; }
 
 # IFS
 # We need space, tab and new line, in precisely that order.
@@ -8123,10 +9257,34 @@ as_nl='
 IFS="  $as_nl"
 
 # CDPATH.
-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; }
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
 
 exec 6>&1
 
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by gc $as_me 6.2, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
 _ACEOF
 
 # Files that config.status was made for.
@@ -8146,7 +9304,7 @@ if test -n "$ac_config_commands"; then
   echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
 fi
 
-cat >>$CONFIG_STATUS <<\EOF
+cat >>$CONFIG_STATUS <<\_ACEOF
 
 ac_cs_usage="\
 \`$as_me' instantiates files from templates according to the
@@ -8168,12 +9326,12 @@ Configuration commands:
 $config_commands
 
 Report bugs to <bug-autoconf@gnu.org>."
-EOF
+_ACEOF
 
-cat >>$CONFIG_STATUS <<EOF
+cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-gc config.status 6.1
-configured by $0, generated by GNU Autoconf 2.52,
+gc config.status 6.2
+configured by $0, generated by GNU Autoconf 2.53,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
@@ -8182,9 +9340,9 @@ This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 srcdir=$srcdir
 INSTALL="$INSTALL"
-EOF
+_ACEOF
 
-cat >>$CONFIG_STATUS <<\EOF
+cat >>$CONFIG_STATUS <<\_ACEOF
 # If no file are specified by the user, then we need to provide default
 # value.  By we need to know if files were specified by the user.
 ac_need_defaults=:
@@ -8206,18 +9364,18 @@ do
 
   case $1 in
   # Handling of the options.
-EOF
-cat >>$CONFIG_STATUS <<EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
     exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
-EOF
-cat >>$CONFIG_STATUS <<\EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
   --version | --vers* | -V )
     echo "$ac_cs_version"; exit 0 ;;
   --he | --h)
     # Conflict between --help and --header
-    { { echo "$as_me:8220: error: ambiguous option: $1
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
 Try \`$0 --help' for more information." >&5
 echo "$as_me: error: ambiguous option: $1
 Try \`$0 --help' for more information." >&2;}
@@ -8236,7 +9394,7 @@ Try \`$0 --help' for more information." >&2;}
     ac_need_defaults=false;;
 
   # This is an error.
-  -*) { { echo "$as_me:8239: error: unrecognized option: $1
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
 Try \`$0 --help' for more information." >&5
 echo "$as_me: error: unrecognized option: $1
 Try \`$0 --help' for more information." >&2;}
@@ -8248,25 +9406,9 @@ Try \`$0 --help' for more information." >&2;}
   shift
 done
 
-exec 5>>config.log
-cat >&5 << _ACEOF
-
-## ----------------------- ##
-## Running config.status.  ##
-## ----------------------- ##
-
-This file was extended by $as_me (gc 6.1) 2.52, executed with
-  CONFIG_FILES    = $CONFIG_FILES
-  CONFIG_HEADERS  = $CONFIG_HEADERS
-  CONFIG_LINKS    = $CONFIG_LINKS
-  CONFIG_COMMANDS = $CONFIG_COMMANDS
-  > $ac_cs_invocation
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-
 _ACEOF
-EOF
 
-cat >>$CONFIG_STATUS <<EOF
+cat >>$CONFIG_STATUS <<_ACEOF
 #
 # INIT-COMMANDS section.
 #
@@ -8274,24 +9416,26 @@ cat >>$CONFIG_STATUS <<EOF
 AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
 srcdir=${srcdir}
 host=${host}
-with_multisubdir=${with_multisubdir}
-ac_configure_args="${multilib_arg} ${ac_configure_args}"
 CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-gc_basedir=${gc_basedir}
 CC="${CC}"
 DEFS="$DEFS"
 
-EOF
 
-cat >>$CONFIG_STATUS <<\EOF
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
 for ac_config_target in $ac_config_targets
 do
   case "$ac_config_target" in
   # Handling of arguments.
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+  "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
   "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
   "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
-  *) { { echo "$as_me:8294: error: invalid argument: $ac_config_target" >&5
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
    { (exit 1); exit 1; }; };;
   esac
@@ -8328,9 +9472,9 @@ $debug ||
    { (exit 1); exit 1; }
 }
 
-EOF
+_ACEOF
 
-cat >>$CONFIG_STATUS <<EOF
+cat >>$CONFIG_STATUS <<_ACEOF
 
 #
 # CONFIG_FILES section.
@@ -8343,6 +9487,12 @@ if test -n "\$CONFIG_FILES"; then
   sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
    s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
 s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
 s,@exec_prefix@,$exec_prefix,;t t
 s,@prefix@,$prefix,;t t
 s,@program_transform_name@,$program_transform_name,;t t
@@ -8358,20 +9508,26 @@ s,@includedir@,$includedir,;t t
 s,@oldincludedir@,$oldincludedir,;t t
 s,@infodir@,$infodir,;t t
 s,@mandir@,$mandir,;t t
-s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
 s,@build_alias@,$build_alias,;t t
 s,@host_alias@,$host_alias,;t t
 s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
 s,@ECHO_C@,$ECHO_C,;t t
 s,@ECHO_N@,$ECHO_N,;t t
 s,@ECHO_T@,$ECHO_T,;t t
-s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s,@DEFS@,$DEFS,;t t
 s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
 s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
 s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
 s,@INSTALL_DATA@,$INSTALL_DATA,;t t
@@ -8389,14 +9545,7 @@ s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
 s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
 s,@AWK@,$AWK,;t t
 s,@SET_MAKE@,$SET_MAKE,;t t
-s,@build@,$build,;t t
-s,@build_cpu@,$build_cpu,;t t
-s,@build_vendor@,$build_vendor,;t t
-s,@build_os@,$build_os,;t t
-s,@host@,$host,;t t
-s,@host_cpu@,$host_cpu,;t t
-s,@host_vendor@,$host_vendor,;t t
-s,@host_os@,$host_os,;t t
+s,@GC_VERSION@,$GC_VERSION,;t t
 s,@CC@,$CC,;t t
 s,@CFLAGS@,$CFLAGS,;t t
 s,@LDFLAGS@,$LDFLAGS,;t t
@@ -8424,14 +9573,20 @@ s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
 s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
 s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
 s,@MAINT@,$MAINT,;t t
-s,@gc_basedir@,$gc_basedir,;t t
 s,@GC_CFLAGS@,$GC_CFLAGS,;t t
 s,@THREADLIBS@,$THREADLIBS,;t t
+s,@POWERPC_DARWIN_TRUE@,$POWERPC_DARWIN_TRUE,;t t
+s,@POWERPC_DARWIN_FALSE@,$POWERPC_DARWIN_FALSE,;t t
 s,@EXTRA_TEST_LIBS@,$EXTRA_TEST_LIBS,;t t
 s,@target_all@,$target_all,;t t
+s,@CPLUSPLUS_TRUE@,$CPLUSPLUS_TRUE,;t t
+s,@CPLUSPLUS_FALSE@,$CPLUSPLUS_FALSE,;t t
 s,@INCLUDES@,$INCLUDES,;t t
 s,@CXXINCLUDES@,$CXXINCLUDES,;t t
 s,@addobjs@,$addobjs,;t t
+s,@addincludes@,$addincludes,;t t
+s,@addlibs@,$addlibs,;t t
+s,@addtests@,$addtests,;t t
 s,@LN_S@,$LN_S,;t t
 s,@ECHO@,$ECHO,;t t
 s,@CPP@,$CPP,;t t
@@ -8441,9 +9596,9 @@ s,@USE_LIBDIR_TRUE@,$USE_LIBDIR_TRUE,;t t
 s,@USE_LIBDIR_FALSE@,$USE_LIBDIR_FALSE,;t t
 CEOF
 
-EOF
+_ACEOF
 
-  cat >>$CONFIG_STATUS <<\EOF
+  cat >>$CONFIG_STATUS <<\_ACEOF
   # 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_lines=48
@@ -8482,8 +9637,8 @@ EOF
   fi
 fi # test -n "$CONFIG_FILES"
 
-EOF
-cat >>$CONFIG_STATUS <<\EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
 for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
   # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case $ac_file in
@@ -8497,7 +9652,8 @@ for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
   esac
 
   # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
-  ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          X"$ac_file" : 'X\(//\)[^/]' \| \
          X"$ac_file" : 'X\(//\)$' \| \
          X"$ac_file" : 'X\(/\)' \| \
@@ -8508,8 +9664,7 @@ echo X"$ac_file" |
          /^X\(\/\/\)$/{ s//\1/; q; }
          /^X\(\/\).*/{ s//\1/; q; }
          s/.*/./; q'`
-  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
-    { case "$ac_dir" in
+  { case "$ac_dir" in
   [\\/]* | ?:[\\/]* ) as_incr_dir=;;
   *)                      as_incr_dir=.;;
 esac
@@ -8520,48 +9675,68 @@ for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
     ?:) as_incr_dir=$as_mkdir_dir ;;
     *)
       as_incr_dir=$as_incr_dir/$as_mkdir_dir
-      test -d "$as_incr_dir" || mkdir "$as_incr_dir"
+      test -d "$as_incr_dir" ||
+        mkdir "$as_incr_dir" ||
+       { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }
     ;;
   esac
 done; }
 
-    ac_dir_suffix="/`echo $ac_dir|sed 's,^\./,,'`"
-    # A "../" for each directory in $ac_dir_suffix.
-    ac_dots=`echo "$ac_dir_suffix" | sed 's,/[^/]*,../,g'`
-  else
-    ac_dir_suffix= ac_dots=
-  fi
+  ac_builddir=.
 
-  case $srcdir in
-  .)  ac_srcdir=.
-      if test -z "$ac_dots"; then
-         ac_top_srcdir=.
-      else
-         ac_top_srcdir=`echo $ac_dots | sed 's,/$,,'`
-      fi ;;
-  [\\/]* | ?:[\\/]* )
-      ac_srcdir=$srcdir$ac_dir_suffix;
-      ac_top_srcdir=$srcdir ;;
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
   *) # Relative path.
-    ac_srcdir=$ac_dots$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_dots$srcdir ;;
-  esac
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
 
   case $INSTALL in
   [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
-  *) ac_INSTALL=$ac_dots$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
   if test x"$ac_file" != x-; then
-    { echo "$as_me:8556: creating $ac_file" >&5
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
 echo "$as_me: creating $ac_file" >&6;}
     rm -f "$ac_file"
   fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
-  #    /* config.h.  Generated automatically by config.status.  */
-  configure_input="Generated automatically from `echo $ac_file_in |
-                                                 sed 's,.*/,,'` by configure."
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
 
   # First look for the input files in the build tree, otherwise in the
   # src tree.
@@ -8571,7 +9746,7 @@ echo "$as_me: creating $ac_file" >&6;}
       -) echo $tmp/stdin ;;
       [\\/$]*)
          # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:8574: error: cannot find input file: $f" >&5
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
          echo $f;;
@@ -8584,23 +9759,29 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
            echo $srcdir/$f
          else
            # /dev/null tree
-           { { echo "$as_me:8587: error: cannot find input file: $f" >&5
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
          fi;;
       esac
     done` || { (exit 1); exit 1; }
-EOF
-cat >>$CONFIG_STATUS <<EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
 $extrasub
-EOF
-cat >>$CONFIG_STATUS <<\EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
 s,@configure_input@,$configure_input,;t t
 s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
 s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
 s,@INSTALL@,$ac_INSTALL,;t t
 " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
   rm -f $tmp/stdin
@@ -8612,8 +9793,8 @@ s,@INSTALL@,$ac_INSTALL,;t t
   fi
 
 done
-EOF
-cat >>$CONFIG_STATUS <<\EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
 
 #
 # CONFIG_COMMANDS section.
@@ -8621,13 +9802,66 @@ cat >>$CONFIG_STATUS <<\EOF
 for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
   ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
   ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_dest" : 'X\(//\)[^/]' \| \
+         X"$ac_dest" : 'X\(//\)$' \| \
+         X"$ac_dest" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
 
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
   case $ac_dest in
     depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
   # Strip MF so we end up with the name of the file.
   mf=`echo "$mf" | sed -e 's/:.*$//'`
-  if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
-    dirpart=`$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          X"$mf" : 'X\(//\)[^/]' \| \
          X"$mf" : 'X\(//\)$' \| \
          X"$mf" : 'X\(/\)' \| \
@@ -8665,7 +9899,8 @@ echo X"$mf" |
        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
     # Make sure the directory exists.
     test -f "$dirpart/$file" && continue
-    fdir=`$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          X"$file" : 'X\(//\)[^/]' \| \
          X"$file" : 'X\(//\)$' \| \
          X"$file" : 'X\(/\)' \| \
@@ -8687,7 +9922,11 @@ for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
     ?:) as_incr_dir=$as_mkdir_dir ;;
     *)
       as_incr_dir=$as_incr_dir/$as_mkdir_dir
-      test -d "$as_incr_dir" || mkdir "$as_incr_dir"
+      test -d "$as_incr_dir" ||
+        mkdir "$as_incr_dir" ||
+       { { echo "$as_me:$LINENO: error: cannot create $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }
     ;;
   esac
 done; }
@@ -8699,15 +9938,16 @@ done
  ;;
   esac
 done
-EOF
+_ACEOF
 
-cat >>$CONFIG_STATUS <<\EOF
+cat >>$CONFIG_STATUS <<\_ACEOF
 
 { (exit 0); exit 0; }
-EOF
+_ACEOF
 chmod +x $CONFIG_STATUS
 ac_clean_files=$ac_clean_files_save
 
+
 # configure is writing to config.log, and then calls config.status.
 # config.status does its own redirection, appending to config.log.
 # Unfortunately, on DOS this fails, as config.log is still kept open
index da2b5b31a0e9c1a91d60f94003da3e839dbac233..068ee39a42a972ab29c5a80cfafca7ce03a2ba98 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
-    ;;
-    *-*-hpux* )
-    gc_cflags=+ESdbgasm
-    ;;
-esac
+if test :"$GCC": = :yes: ; then
+    gc_cflags="${gc_cflags} -fexceptions"
+else
+    case "$host" in 
+        *-*-hpux* )
+        gc_cflags="${gc_flags} +ESdbgasm"
+        # :TODO: actaully we should check using Autoconf if
+        #     the compiler supports this option.
+        ;;
+    esac
+fi
 
 case "${target_optspace}:${host}" in
   yes:*)
index 8e2c9494fac32984563584c40b4627a19d9f86b4..4f9e0d756bdd705e5dbaa4c49ea4419e870d00fa 100644 (file)
 # modified is included with the above copyright notice.
 #
 # Original author: Tom Tromey
+# Modified by: Grzegorz Jakacki <jakacki at acm dot org>
 
 dnl Process this file with autoconf to produce configure.
 
-AC_INIT(gc, 6.1, Hans_Boehm@hp.com)
-
-AM_INIT_AUTOMAKE(gc, 6.1, no-define)
+# Initialization
+# ==============
 
+AC_INIT(gc,6.2,Hans.Boehm@hp.com) 
+    ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
 AC_CONFIG_SRCDIR(gcj_mlc.c)
+AC_CANONICAL_TARGET 
+AC_PREREQ(2.53)
+AC_REVISION($Revision: 1.2 $)
+GC_SET_VERSION
+AM_INIT_AUTOMAKE
 
-dnl Can't be done in GC_CONFIGURE because that confuses automake. 
-dnl AC_CONFIG_AUX_DIR(.)
-
-AC_CANONICAL_HOST
+AC_SUBST(PACKAGE)
+AC_SUBST(GC_VERSION)
 
 AC_PROG_CC
 AC_PROG_CXX
 
 AM_PROG_AS
 AC_CHECK_TOOL(AR, ar)
-AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(RANLIB, ranlib, :)  # :)
 
 AC_PROG_INSTALL
 
 AM_MAINTAINER_MODE
 
-if test "[$]{srcdir}" = "."; then
-  if test "[$]{with_target_subdir}" != "." -a -n "[$]{with_target_subdir}"; then
-    gc_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1"
-  else
-    gc_basedir="[$]{srcdir}/[$]{with_multisrctop}$1"
-  fi
-else
-  gc_basedir="[$]{srcdir}/$1"
-fi
-AC_SUBST(gc_basedir)
-
-# We need AC_EXEEXT to keep automake happy in cygnus mode.  However,
-# at least currently, we never actually build a program, so we never
-# need to use $(EXEEXT).  Moreover, the test for EXEEXT normally
-# fails, because we are probably configuring with a cross compiler
-# which can't create executables.  So we include AC_EXEEXT to keep
-# automake happy, but we don't execute it, since we don't care about
-# the result.
-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
-
 . [$]{srcdir}/configure.host
 
 GC_CFLAGS=${gc_cflags}
@@ -84,6 +63,10 @@ AC_ARG_ENABLE(parallel-mark,
     esac]
 )
 
+AC_ARG_ENABLE(cplusplus,
+[  --enable-cplusplus          install C++ support],
+)
+
 INCLUDES=-I${srcdir}/include
 THREADLIBS=
 case "$THREADS" in
@@ -106,6 +89,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)
@@ -132,6 +119,13 @@ case "$THREADS" in
      *-*-cygwin*)
        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
@@ -152,6 +146,7 @@ case "$THREADS" in
     ;;
  dgux386)
     THREADS=dgux386
+AC_MSG_RESULT($THREADLIBS)
     # Use pthread GCC  switch
     THREADLIBS=-pthread
     if test "${enable_parallel_mark}" = yes; then
@@ -163,6 +158,12 @@ case "$THREADS" in
     # 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)
     ;;
@@ -172,7 +173,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=libgc.la
@@ -189,6 +205,9 @@ TARGET_ECOS="$with_ecos"
 )
 
 addobjs=
+addlibs=
+addincludes=
+addtests=
 CXXINCLUDES=
 case "$TARGET_ECOS" in
    no)
@@ -199,22 +218,38 @@ 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)
 
-machdep=
+# Configuration of shared libraries
+#
+AC_MSG_CHECKING(whether to build shared libraries)
+AC_ENABLE_SHARED
 
 case "$host" in
  alpha-*-openbsd*)
-     AC_DISABLE_SHARED
+     enable_shared=no
+     AC_MSG_RESULT(no)
      ;;
  *)
-     AC_ENABLE_SHARED
+     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"
@@ -259,29 +294,37 @@ 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
 
-dnl checks for AViiON Machines running DGUX
+#
+# 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
+    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
+    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
+    AC_SUBST(CFLAGS)
+    AC_SUBST(CXXFLAGS)
 fi
 
 dnl We use these options to decide which functions to include.
@@ -291,7 +334,6 @@ AC_ARG_WITH(target-subdir,
 AC_ARG_WITH(cross-host,
 [  --with-cross-host=HOST  configuring with a cross compiler])
 
-AM_MAINTAINER_MODE
 # 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.
@@ -303,13 +345,14 @@ if false; then
   AC_EXEEXT
 fi
 
-AC_MSG_CHECKING([for threads package to use])
-
 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*)
     if test "$GCC" = yes; then
+       AC_MSG_RESULT(yes)
        new_CFLAGS=
        for i in $CFLAGS; do
          case "$i" in
@@ -321,8 +364,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.
@@ -385,21 +431,18 @@ if test "${enable_redirect_malloc}" = yes; then
     fi
 fi
 
-AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
-
-if test "${multilib}" = "yes"; then
-  multilib_arg="--enable-multilib"
-else
-  multilib_arg=
+AC_ARG_ENABLE(gc-assertions,
+[  --enable-gc-assertions  collector-internal assertion checking])
+if test "${enable_gc_assertions}" = yes; then
+    AC_DEFINE(GC_ASSERTIONS)
 fi
 
-AC_OUTPUT(Makefile,,
+AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
+
+AC_OUTPUT([Makefile doc/Makefile include/Makefile],,
 srcdir=${srcdir}
 host=${host}
-with_multisubdir=${with_multisubdir}
-ac_configure_args="${multilib_arg} ${ac_configure_args}"
 CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-gc_basedir=${gc_basedir}
 CC="${CC}"
 DEFS="$DEFS"
 )
index 9fc894d4946e0da9d066fe1fb18f00ba8d9d9ae0..d83f4067de76dda23893f0f9575db9f084bb6fea 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 fedbfbe67c25becc9f082aa3bb3e4f0c3d4f351f..0bbd676a3355d226eaf9e3d56895c7b9f6c95340 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:
diff --git a/darwin_stop_world.c b/darwin_stop_world.c
new file mode 100644 (file)
index 0000000..bc2247f
--- /dev/null
@@ -0,0 +1,209 @@
+#include "private/pthread_support.h"
+
+# if defined(GC_DARWIN_THREADS)
+
+#define DEBUG_THREADS 0
+
+/* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
+   Page 49:
+   "The space beneath the stack pointer, where a new stack frame would normally
+   be allocated, is called the red zone. This area as shown in Figure 3-2 may
+   be used for any purpose as long as a new stack frame does not need to be
+   added to the stack."
+   
+   Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then
+   it must set up a stack frame just like routines that call other routines."
+*/
+#define PPC_RED_ZONE_SIZE 224
+
+void GC_push_all_stacks() {
+    int i;
+    kern_return_t r;
+    GC_thread p;
+    pthread_t me;
+    ptr_t lo, hi;
+#      if defined(POWERPC)
+        ppc_thread_state_t state;
+#      else
+#              error FIXME for non-ppc OS X
+#      endif
+    mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
+    
+    me = pthread_self();
+    if (!GC_thr_initialized) GC_thr_init();
+    
+    for(i=0;i<THREAD_TABLE_SZ;i++) {
+        for(p=GC_threads[i];p!=0;p=p->next) {
+            if(p -> flags & FINISHED) continue;
+            if(pthread_equal(p->id,me)) {
+                lo = GC_approx_sp();
+            } else {
+                /* Get the thread state (registers, etc) */
+                r = thread_get_state(
+                    p->stop_info.mach_thread,
+                    MACHINE_THREAD_STATE,
+                    (natural_t*)&state,
+                    &thread_state_count);
+                if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
+    
+                #ifdef POWERPC
+                    lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE);
+                    
+                    GC_push_one(state.r0); 
+                    GC_push_one(state.r2); 
+                    GC_push_one(state.r3); 
+                    GC_push_one(state.r4); 
+                    GC_push_one(state.r5); 
+                    GC_push_one(state.r6); 
+                    GC_push_one(state.r7); 
+                    GC_push_one(state.r8); 
+                    GC_push_one(state.r9); 
+                    GC_push_one(state.r10); 
+                    GC_push_one(state.r11); 
+                    GC_push_one(state.r12); 
+                    GC_push_one(state.r13); 
+                    GC_push_one(state.r14); 
+                    GC_push_one(state.r15); 
+                    GC_push_one(state.r16); 
+                    GC_push_one(state.r17); 
+                    GC_push_one(state.r18); 
+                    GC_push_one(state.r19); 
+                    GC_push_one(state.r20); 
+                    GC_push_one(state.r21); 
+                    GC_push_one(state.r22); 
+                    GC_push_one(state.r23); 
+                    GC_push_one(state.r24); 
+                    GC_push_one(state.r25); 
+                    GC_push_one(state.r26); 
+                    GC_push_one(state.r27); 
+                    GC_push_one(state.r28); 
+                    GC_push_one(state.r29); 
+                    GC_push_one(state.r30); 
+                    GC_push_one(state.r31);
+                #else
+                #      error FIXME for non-PPC darwin
+                #endif /* !POWERPC */
+            } /* p != me */
+            if(p->flags & MAIN_THREAD)
+                hi = GC_stackbottom;
+            else
+                hi = p->stack_end;
+            #if DEBUG_THREADS
+                GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n",
+                    (unsigned long) p -> id,
+                    (unsigned long) lo,
+                    (unsigned long) hi
+                );
+            #endif
+            GC_push_all_stack(lo,hi);
+        } /* for(p=GC_threads[i]...) */
+    } /* for(i=0;i<THREAD_TABLE_SZ...) */
+}
+
+/* Caller holds allocation lock.       */
+void GC_stop_world()
+{
+    int i;
+    GC_thread p;
+    pthread_t my_thread = pthread_self();
+    kern_return_t kern_result;
+    
+    #if DEBUG_THREADS
+    GC_printf1("Stopping the world from 0x%lx\n", pthread_self());
+    #endif
+       
+    /* Make sure all free list construction has stopped before we start. */
+    /* No new construction can start, since free list construction is  */
+    /* required to acquire and release the GC lock before it starts,   */
+    /* and we have the lock.                                           */
+#   ifdef PARALLEL_MARK
+      GC_acquire_mark_lock();
+      GC_ASSERT(GC_fl_builder_count == 0);
+      /* We should have previously waited for it to become zero. */
+#   endif /* PARALLEL_MARK */
+
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+        for (p = GC_threads[i]; p != 0; p = p -> next) {
+            if (p -> id == my_thread) continue;
+            if (p -> flags & FINISHED) continue;
+            if (p -> thread_blocked) /* Will wait */ continue;
+            
+            #if DEBUG_THREADS
+            GC_printf1("Suspending thread 0x%lx\n", p -> id);
+            #endif
+            
+            /* Suspend the thread */
+            kern_result = thread_suspend(p->stop_info.mach_thread);
+            if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed");
+            
+            /* This is only needed if we are modifying the threads 
+               state. thread_abort_safely should also be used
+               if this code is ever added in again.
+               
+               kern_result = thread_abort(p->stop_info.mach_thread);
+               if(kern_result != KERN_SUCCESS)
+                   ABORT("thread_abort failed (%ul)",kern_result);
+            */
+        }
+    }
+    
+#   ifdef MPROTECT_VDB
+    if(GC_incremental) {
+        extern void GC_mprotect_stop();
+        GC_mprotect_stop();
+    }
+#   endif
+    
+#   ifdef PARALLEL_MARK
+      GC_release_mark_lock();
+#   endif
+    #if DEBUG_THREADS
+      GC_printf1("World stopped from 0x%lx\n", pthread_self());
+    #endif
+}
+
+/* Caller holds allocation lock, and has held it continuously since    */
+/* the world stopped.                                                  */
+void GC_start_world()
+{
+    pthread_t my_thread = pthread_self();
+    int i;
+    GC_thread p;
+    kern_return_t kern_result;
+
+#   if DEBUG_THREADS
+      GC_printf0("World starting\n");
+#   endif
+
+#   ifdef MPROTECT_VDB
+    if(GC_incremental) {
+        extern void GC_mprotect_resume();
+        GC_mprotect_resume();
+    }
+#   endif
+
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+        for (p = GC_threads[i]; p != 0; p = p -> next) {
+            if (p -> id == my_thread) continue;
+            if (p -> flags & FINISHED) continue;
+            if (p -> thread_blocked) continue;
+    
+            #if DEBUG_THREADS
+            GC_printf1("Resuming 0x%lx\n", p -> id);
+            #endif
+            
+            /* Resume the thread */
+            kern_result = thread_resume(p->stop_info.mach_thread);
+            if(kern_result != KERN_SUCCESS) ABORT("thread_resume failed");
+        }
+    }
+    #if DEBUG_THREADS
+      GC_printf0("World started\n");
+    #endif
+}
+
+void GC_stop_init() {
+
+}
+
+#endif
index a67fef28d35efd501b7563fce933f4442c6cce46..f640930d90184900b57834afdea257885ad63429 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -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()
@@ -442,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.
@@ -460,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));
   }
 
@@ -474,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
@@ -868,9 +924,11 @@ void GC_print_all_smashed_proc ()
 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);
 }
@@ -891,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;
@@ -957,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) {
@@ -989,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) {
@@ -1022,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) {
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..9144630
--- /dev/null
@@ -0,0 +1,27 @@
+# 
+# 
+# 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/doc/Makefile.in b/doc/Makefile.in
new file mode 100644 (file)
index 0000000..9bf1ff5
--- /dev/null
@@ -0,0 +1,282 @@
+# 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 d6dbec90fdfc8119416bfd71d4e33ed0d94ede82..04e24a9a53715f2e006bce84d320261ca7bb283f 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.
@@ -28,7 +28,7 @@ are GPL'ed, but with an exception that should cover all uses in the
 collector.  (If you are concerned about such things, I recommend you look
 at the notice in config.guess or ltmain.sh.)
 
-This is version 6.1 of a conservative garbage collector for C and C++.
+This is version 6.2 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
index 2abf0b400f7f6455297ac9e6f31255c9b45b0309..f5333d51ad6771b17bfe28e6b881583c5ad40f8d 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 3a49e062264e111c7725d4149b8e566ea3926293..1a0fcb387b1431925e82f6dfeb6414b6e1e3dddc 100644 (file)
@@ -1676,16 +1676,216 @@ Since 6.1alpha5:
    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.
+    
+
 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. 
- - The win32 collector ends up tracing some (most?) objects allocated with
-   the system allocator, in spite if the fact that it tries not to.
-   This costs time and space, though it remains correct.
-   We need a way to identify memory regions used by the system malloc(),
-   or an alternate way to locate dll data areas.  A very partial
-   workaround is to use GC_malloc_atomic_uncollectable() instead of
-   the system malloc() for most allocation.
  - There seem to be outstanding issues on Solaris/X86, possibly with
    finding the data segment starting address.  Information/patches would
    be appreciated.
diff --git a/doc/README.darwin b/doc/README.darwin
new file mode 100644 (file)
index 0000000..5bca9e1
--- /dev/null
@@ -0,0 +1,86 @@
+Darwin/MacOSX Support - May 20, 2003
+====================================
+
+Important Usage Notes
+=====================
+
+GC_init() MUST be called before calling any other GC functions. This 
+is necessary to properly register segments in dynamic libraries. This
+call is required even if you code does not use dynamic libraries as the
+dyld code handles registering all data segments.
+
+The incremental collector is still a bit flaky on darwin. It seems to 
+work reliably with workarounds for a few possible bugs in place however
+these workaround may not work correctly in all cases. There may also
+be additional problems that I have not found. 
+
+Implementation Information
+==========================
+Darwin/MacOSX support is nearly complete. Thread support is reliable on 
+Darwin 6.x (MacOSX 10.2) and there have been reports of success on older
+Darwin versions (MacOSX 10.1). Shared library support had also been
+added and the gc can be run from a shared library. There is currently only
+support for Darwin/PPC although adding x86 support should be trivial.
+
+Thread support is implemented in terms of mach thread_suspend and 
+thread_resume calls. These provide a very clean interface to thread
+suspension. This implementation doesn't rely on pthread_kill so the
+code works on Darwin < 6.0 (MacOSX 10.1). All the code to stop the
+world is located in darwin_stop_world.c.
+
+The original incremental collector support unfortunatelly no longer works
+on recent Darwin versions. It also relied on some undocumented kernel
+structures. Mach, however, does have a very clean interface to exception
+handing. The current implementation uses Mach's exception handling. 
+
+Much thanks goes to Andrew Stone, Dietmar Planitzer, Andrew Begel, 
+Jeff Sturm, and Jesse Rosenstock for all their work on the 
+Darwin/OS X port.
+
+-Brian Alliet
+brian@brianweb.net
+
+
+Older Information (Most of this no longer applies to the current code)
+======================================================================
+
+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).
+
+Feb 26, 2003
+
+Jeff Sturm and Jesse Rosenstock provided a patch that adds thread support.
+GC_MACOSX_THREADS should be defined in the build and in clients.  Real
+dynamic library support is still missing, i.e. dynamic library data segments
+are still not scanned.  Code that stores pointers to the garbage collected
+heap in statically allocated variables should not reside in a dynamic
+library.  This still doesn't appear to be 100% reliable.  
+
+Mar 10, 2003
+Brian Alliet contributed dynamic library support for MacOSX.  It could also
+use more testing.
index d9df8dd31a6e2460de77eb8bc96ad43272b3afaf..b5fe6796cc2d42d2905a5278d5e6015ac1d78f99 100644 (file)
@@ -51,7 +51,18 @@ _DLL         Defined by Visual C++ if dynamic libraries are being built
                __declspec(dllexport) needs to be added to declarations
                to support the case in which the collector is in a dll.
 
-GC_DLL         User-settable macro that forces the effect of _DLL.
+GC_DLL         User-settable macro that forces the effect of _DLL.  Set
+               by gc.h if _DLL is defined and GC_NOT_DLL is undefined.
+               This is the macro that is tested internally to determine
+               whether the GC is in its own dynamic library.  May need
+               to be set by clients before including gc.h.  Note that
+               inside the GC implementation it indicates that the
+               collector is in its own dynamic library, should export
+               its symbols, etc.  But in clients it indicates that the
+               GC resides in a different DLL, its entry points should
+               be referenced accordingly, and precautions may need to
+               be taken to properly deal with statically allocated 
+               variables in the main program.  Used only for MS Windows.
 
 GC_NOT_DLL     User-settable macro that overrides _DLL, e.g. if dynamic
                libraries are used, but the collector is in a static library.
index dcccec3aea300f9b5f2e2e1b4f80595e410b25ff..a40b375f5509ff9de9fcea2d009fb4c1a15eb93a 100644 (file)
@@ -25,7 +25,7 @@ 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 arbirtray memory segments obtained from
+unavoidable if you scan arbitrary memory segments obtained from
 VirtualQuery.)
 
 The collector test program "gctest" is linked as a GUI application,
@@ -65,6 +65,12 @@ 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).
@@ -155,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 65e8a8f61c9f81bea9d5643ad478217b3e9e468b..8ecbac8db62e6205e0cd3f9d2375ed2c5efd16b4 100644 (file)
@@ -1,7 +1,7 @@
 <HTML>
 <HEAD>
     <TITLE> Conservative GC Algorithmic Overview </TITLE>
-    <AUTHOR> Hans-J. Boehm, Silicon Graphics</author>
+    <AUTHOR> Hans-J. Boehm, HP Labs (Much of this was written at SGI)</author>
 </HEAD>
 <BODY>
 <H1> <I>This is under construction</i> </h1>
@@ -96,20 +96,24 @@ typically on the order of the page size.
 <P>
 Large block sizes are rounded up to
 the next multiple of <TT>HBLKSIZE</tt> and then allocated by
-<TT>GC_allochblk</tt>.  This uses roughly what Paul Wilson has termed
-a "next fit" algorithm, i.e. first-fit with a rotating pointer.
-The implementation does check for a better fitting immediately
-adjacent block, which gives it somewhat better fragmentation characteristics.
-I'm now convinced it should use a best fit algorithm.  The actual
+<TT>GC_allochblk</tt>.  Recent versions of the collector
+use an approximate best fit algorithm by keeping free lists for
+several large block sizes.
+The actual
 implementation of <TT>GC_allochblk</tt>
 is significantly complicated by black-listing issues
 (see below).
 <P>
-Small blocks are allocated in blocks of size <TT>HBLKSIZE</tt>.
-Each block is
+Small blocks are allocated in chunks of size <TT>HBLKSIZE</tt>.
+Each chunk is
 dedicated to only one object size and kind.  The allocator maintains
 separate free lists for each size and kind of object.
 <P>
+Once a large block is split for use in smaller objects, it can only
+be used for objects of that size, unless the collector discovers a completely
+empty chunk.  Completely empty chunks are restored to the appropriate
+large block free list.
+<P>
 In order to avoid allocating blocks for too many distinct object sizes,
 the collector normally does not directly allocate objects of every possible
 request size.  Instead request are rounded up to one of a smaller number
@@ -139,27 +143,35 @@ expand the heap.  Otherwise, we initiate a garbage collection.  This ensures
 that the amount of garbage collection work per allocated byte remains
 constant.
 <P>
-The above is in fat an oversimplification of the real heap expansion
-heuristic, which adjusts slightly for root size and certain kinds of
-fragmentation.  In particular, programs with a large root set size and
+The above is in fact an oversimplification of the real heap expansion
+and GC triggering heuristic, which adjusts slightly for root size
+and certain kinds of
+fragmentation.  In particular:
+<UL>
+<LI> Programs with a large root set size and
 little live heap memory will expand the heap to amortize the cost of
-scanning the roots.
-<P>
-Versions 5.x of the collector actually collect more frequently in
+scanning the roots.  
+<LI> Versions 5.x of the collector actually collect more frequently in
 nonincremental mode.  The large block allocator usually refuses to split
 large heap blocks once the garbage collection threshold is
 reached.  This often has the effect of collecting well before the
 heap fills up, thus reducing fragmentation and working set size at the
-expense of GC time.  6.x will chose an intermediate strategy depending
+expense of GC time.  Versions 6.x choose an intermediate strategy depending
 on how much large object allocation has taken place in the past.
 (If the collector is configured to unmap unused pages, versions 6.x
-will use the 5.x strategy.)
-<P>
-(It has been suggested that this should be adjusted so that we favor
+use the 5.x strategy.)
+<LI> In calculating the amount of allocation since the last collection we
+give partial credit for objects we expect to be explicitly deallocated.
+Even if all objects are explicitly managed, it is often desirable to collect
+on rare occasion, since that is our only mechanism for coalescing completely
+empty chunks.
+</ul>
+<P>
+It has been suggested that this should be adjusted so that we favor
 expansion if the resulting heap still fits into physical memory.
 In many cases, that would no doubt help.  But it is tricky to do this
 in a way that remains robust if multiple application are contending
-for a single pool of physical memory.)
+for a single pool of physical memory.
 
 <H2>Mark phase</h2>
 
@@ -204,7 +216,7 @@ changes to
 <LI> <TT>MS_NONE</tt> indicating that reachable objects are marked.
 </ol>
 
-The core mark routine <TT>GC_mark_from_mark_stack</tt>, is called
+The core mark routine <TT>GC_mark_from</tt>, is called
 repeatedly by several of the sub-phases when the mark stack starts to fill
 up.  It is also called repeatedly in <TT>MS_ROOTS_PUSHED</tt> state
 to empty the mark stack.
@@ -213,6 +225,12 @@ each call, so that it can also be used by the incremental collector.
 It is fairly carefully tuned, since it usually consumes a large majority
 of the garbage collection time.
 <P>
+The fact that it perform a only a small amount of work per call also
+allows it to be used as the core routine of the parallel marker.  In that
+case it is normally invoked on thread-private mark stacks instead of the
+global mark stack.  More details can be found in
+<A HREF="scale.html">scale.html</a>
+<P>
 The marker correctly handles mark stack overflows.  Whenever the mark stack
 overflows, the mark state is reset to <TT>MS_INVALID</tt>.
 Since there are already marked objects in the heap,
@@ -281,7 +299,8 @@ Unmarked large objects are immediately returned to the large object free list.
 Each small object page is checked to see if all mark bits are clear.
 If so, the entire page is returned to the large object free list.
 Small object pages containing some reachable object are queued for later
-sweeping.
+sweeping, unless we determine that the page contains very little free
+space, in which case it is not examined further.
 <P>
 This initial sweep pass touches only block headers, not
 the blocks themselves.  Thus it does not require significant paging, even
@@ -341,12 +360,16 @@ object itself becomes marked, we have uncovered
 a cycle involving the object.  This usually results in a warning from the
 collector.  Such objects are not finalized, since it may be
 unsafe to do so.  See the more detailed
-<A HREF="finalization.html"> discussion of finalization semantics</a>.
+<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/finalization.html"> discussion of finalization semantics</a>.
 <P>
 Any objects remaining unmarked at the end of this process are added to
 a queue of objects whose finalizers can be run.  Depending on collector
 configuration, finalizers are dequeued and run either implicitly during
 allocation calls, or explicitly in response to a user request.
+(Note that the former is unfortunately both the default and not generally safe.
+If finalizers perform synchronization, it may result in deadlocks.
+Nontrivial finalizers generally need to perform synchronization, and
+thus require a different collector configuration.)
 <P>
 The collector provides a mechanism for replacing the procedure that is
 used to mark through objects.  This is used both to provide support for
@@ -354,13 +377,14 @@ Java-style unordered finalization, and to ignore certain kinds of cycles,
 <I>e.g.</i> those arising from C++ implementations of virtual inheritance.
 
 <H2>Generational Collection and Dirty Bits</h2>
-We basically use the parallel and generational GC algorithm described in
-<A HREF="papers/pldi91.ps.gz">"Mostly Parallel Garbage Collection"</a>,
+We basically use the concurrent and generational GC algorithm described in
+<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi91.ps.Z">"Mostly Parallel Garbage Collection"</a>,
 by Boehm, Demers, and Shenker.
 <P>
 The most significant modification is that
-the collector always runs in the allocating thread.
-There is no separate garbage collector thread.
+the collector always starts running in the allocating thread.
+There is no separate garbage collector thread.  (If parallel GC is
+enabled, helper threads may also be woken up.)
 If an allocation attempt either requests a large object, or encounters
 an empty small object free list, and notices that there is a collection
 in progress, it immediately performs a small amount of marking work
@@ -389,50 +413,108 @@ cannot be satisfied from small object free lists. When marking completes,
 the set of modified pages is retrieved, and we mark once again from
 marked objects on those pages, this time with the mutator stopped.
 <P>
-We keep track of modified pages using one of three distinct mechanisms:
+We keep track of modified pages using one of several distinct mechanisms:
 <OL>
 <LI>
 Through explicit mutator cooperation.  Currently this requires
-the use of <TT>GC_malloc_stubborn</tt>.
+the use of <TT>GC_malloc_stubborn</tt>, and is rarely used.
 <LI>
-By write-protecting physical pages and catching write faults.  This is
+(<TT>MPROTECT_VDB</tt>) By write-protecting physical pages and
+catching write faults.  This is
 implemented for many Unix-like systems and for win32.  It is not possible
 in a few environments.
 <LI>
-By retrieving dirty bit information from /proc.  (Currently only Sun's
+(<TT>PROC_VDB</tt>) By retrieving dirty bit information from /proc.
+(Currently only Sun's
 Solaris supports this.  Though this is considerably cleaner, performance
 may actually be better with mprotect and signals.)
+<LI>
+(<TT>PCR_VDB</tt>) By relying on an external dirty bit implementation, in this
+case the one in Xerox PCR.
+<LI>
+(<TT>DEFAULT_VDB</tt>) By treating all pages as dirty.  This is the default if 
+none of the other techniques is known to be usable, and
+<TT>GC_malloc_stubborn</tt> is not used.  Practical only for testing, or if
+the vast majority of objects use <TT>GC_malloc_stubborn</tt>.
 </ol>
 
+<H2>Black-listing</h2>
+
+The collector implements <I>black-listing</i> of pages, as described
+in
+<A HREF="http://www.acm.org/pubs/citations/proceedings/pldi/155090/p197-boehm/">
+Boehm, ``Space Efficient Conservative Collection'', PLDI '93</a>, also available
+<A HREF="papers/pldi93.ps.Z">here</a>.
+<P>
+During the mark phase, the collector tracks ``near misses'', i.e. attempts
+to follow a ``pointer'' to just outside the garbage-collected heap, or
+to a currently unallocated page inside the heap.  Pages that have been
+the targets of such near misses are likely to be the targets of
+misidentified ``pointers'' in the future.  To minimize the future
+damage caused by such misidentifications they will be allocated only to
+small pointerfree objects. 
+<P>
+The collector understands two different kinds of black-listing.  A
+page may be black listed for interior pointer references
+(<TT>GC_add_to_black_list_stack</tt>), if it was the target of a near
+miss from a location that requires interior pointer recognition,
+<I>e.g.</i> the stack, or the heap if <TT>GC_all_interior_pointers</tt>
+is set.  In this case, we also avoid allocating large blocks that include
+this page.
+<P>
+If the near miss came from a source that did not require interior
+pointer recognition, it is black-listed with
+<TT>GC_add_to_black_list_normal</tt>.
+A page black-listed in this way may appear inside a large object,
+so long as it is not the first page of a large object.
+<P>
+The <TT>GC_allochblk</tt> routine respects black-listing when assigning
+a block to a particular object kind and size.  It occasionally
+drops (i.e. allocates and forgets) blocks that are completely black-listed
+in order to avoid excessively long large block free lists containing
+only unusable blocks.  This would otherwise become an issue
+if there is low demand for small pointerfree objects.
+
 <H2>Thread support</h2>
 We support several different threading models.  Unfortunately Pthreads,
 the only reasonably well standardized thread model, supports too narrow
 an interface for conservative garbage collection.  There appears to be
-no portable way to allow the collector to coexist with various Pthreads
+no completely portable way to allow the collector to coexist with various Pthreads
 implementations.  Hence we currently support only a few of the more
 common Pthreads implementations.
 <P>
 In particular, it is very difficult for the collector to stop all other
 threads in the system and examine the register contents.  This is currently
-accomplished with very different mechanisms for different Pthreads
+accomplished with very different mechanisms for some Pthreads
 implementations.  The Solaris implementation temporarily disables much
 of the user-level threads implementation by stopping kernel-level threads
-("lwp"s).  The Irix implementation sends signals to individual Pthreads
-and has them wait in the signal handler.  The Linux implementation
-is similar in spirit to the Irix one.
+("lwp"s).  The Linux/HPUX/OSF1 and Irix implementations sends signals to
+individual Pthreads and has them wait in the signal handler.
 <P>
-The Irix implementation uses
-only documented Pthreads calls, but relies on extensions to their semantics,
-notably the use of mutexes and condition variables from signal
-handlers.  The Linux implementation should be far closer to
-portable, though impirically it is not completely portable.
+The Linux and Irix implementations use
+only documented Pthreads calls, but rely on extensions to their semantics.
+The Linux implementation <TT>linux_threads.c</tt> relies on only very
+mild extensions to the pthreads semantics, and already supports a large number
+of other Unix-like pthreads implementations.  Our goal is to make this the
+only pthread support in the collector.
+<P>
+(The Irix implementation is separate only for historical reasons and should
+clearly be merged.  The current Solaris implementation probably performs
+better in the uniprocessor case, but does not support thread operations in the
+collector.  Hence it cannot support the parallel marker.)
 <P>
 All implementations must
 intercept thread creation and a few other thread-specific calls to allow
 enumeration of threads and location of thread stacks.  This is current
-accomplished with <TT># define</tt>'s in <TT>gc.h</tt>, or optionally
+accomplished with <TT># define</tt>'s in <TT>gc.h</tt>
+(really <TT>gc_pthread_redirects.h</tt>), or optionally
 by using ld's function call wrapping mechanism under Linux.
 <P>
 Comments are appreciated.  Please send mail to
-<A HREF="mailto:boehm@acm.org"><TT>boehm@acm.org</tt></a>
+<A HREF="mailto:boehm@acm.org"><TT>boehm@acm.org</tt></a> or
+<A HREF="mailto:Hans.Boehm@hp.com"><TT>Hans.Boehm@hp.com</tt></a>
+<P>
+This is a modified copy of a page written while the author was at SGI.
+The original was <A HREF="http://reality.sgi.com/boehm/gcdescr.html">here</a>.
 </body>
+</html>
diff --git a/doc/gcinterface.html b/doc/gcinterface.html
new file mode 100644 (file)
index 0000000..7b336ec
--- /dev/null
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML>
+<HEAD>
+<TITLE>Garbage Collector Interface</TITLE>
+</HEAD>
+<BODY>
+<H1>C Interface</h1>
+On many platforms, a single-threaded garbage collector library can be built
+to act as a plug-in malloc replacement.  (Build with -DREDIRECT_MALLOC=GC_malloc
+-DIGNORE_FREE.)  This is often the best way to deal with third-party libraries
+which leak or prematurely free objects.  -DREDIRECT_MALLOC is intended
+primarily as an easy way to adapt old code, not for new development.
+<P>
+New code should use the interface discussed below.
+<P>
+Code must be linked against the GC library.  On most UNIX platforms,
+this will be gc.a.
+<P>
+The following describes the standard C interface to the garbage collector.
+It is not a complete definition of the interface.  It describes only the
+most commonly used functionality, approximately in decreasing order of
+frequency of use.  The description assumes an ANSI C compiler.
+The full interface is described in
+<A HREF="http://hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gch.txt">gc.h</a>
+or <TT>gc.h</tt> in the distribution.
+<P>
+Clients should include gc.h.
+<P>
+In the case of multithreaded code,
+gc.h should be included after the threads header file, and
+after defining the appropriate GC_XXXX_THREADS macro.
+(For 6.2alpha4 and later, simply defining GC_THREADS should suffice.)
+Gc.h must be included
+in files that use either GC or threads primitives, since threads primitives
+will be redefined to cooperate with the GC on many platforms.
+<DL>
+<DT> <B>void * GC_MALLOC(size_t <I>nbytes</i>)</b>
+<DD>
+Allocates and clears <I>nbytes</i> of storage.
+Requires (amortized) time proportional to <I>nbytes</i>.
+The resulting object will be automatically deallocated when unreferenced.
+References from objects allocated with the system malloc are usually not
+considered by the collector.  (See GC_MALLOC_UNCOLLECTABLE, however.)
+GC_MALLOC is a macro which invokes GC_malloc by default or, if GC_DEBUG
+is defined before gc.h is included, a debugging version that checks
+occasionally for overwrite errors, and the like.
+<DT> <B>void * GC_MALLOC_ATOMIC(size_t <I>nbytes</i>)</b>
+<DD>
+Allocates <I>nbytes</i> of storage.
+Requires (amortized) time proportional to <I>nbytes</i>.
+The resulting object will be automatically deallocated when unreferenced.
+The client promises that the resulting object will never contain any pointers.
+The memory is not cleared.
+This is the preferred way to allocate strings, floating point arrays,
+bitmaps, etc.
+More precise information about pointer locations can be communicated to the
+collector using the interface in
+<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc_typedh.txt">gc_typed.h</a> in the distribution.
+<DT> <B>void * GC_MALLOC_UNCOLLECTABLE(size_t <I>nbytes</i>)</b>
+<DD>
+Identical to GC_MALLOC, except that the resulting object is not automatically
+deallocated.  Unlike the system-provided malloc, the collector does
+scan the object for pointers to garbage-collectable memory, even if the
+block itself does not appear to be reachable.  (Objects allocated in this way
+are effectively treated as roots by the collector.)
+<DT> <B> void * GC_REALLOC(void *old, size_t new_size) </b>
+<DD>
+Allocate a new object of the indicated size and copy (a prefix of) the
+old object into the new object.  The old object is reused in place if
+convenient.  If the original object was allocated with GC_malloc_atomic,
+the new object is subject to the same constraints.  If it was allocated
+as an uncollectable object, then the new object is uncollectable, and
+the old object (if different) is deallocated.
+(Use GC_REALLOC with GC_MALLOC, etc.)
+<DT> <B> void GC_FREE(void *dead) </b>
+<DD>
+Explicitly deallocate an object.  Typically not useful for small
+collectable objects.  (Use GC_FREE with GC_MALLOC, etc.)
+<DT> <B> void * GC_MALLOC_IGNORE_OFF_PAGE(size_t <I>nbytes</i>) </b>
+<DD>
+<DT> <B> void * GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(size_t <I>nbytes</i>) </b>
+<DD>
+Analogous to GC_MALLOC and GC_MALLOC_ATOMIC, except that the client
+guarantees that as long
+as the resulting object is of use, a pointer is maintained to someplace
+inside the first 512 bytes of the object.  This pointer should be declared
+volatile to avoid interference from compiler optimizations.
+(Other nonvolatile pointers to the object may exist as well.)
+This is the
+preferred way to allocate objects that are likely to be > 100KBytes in size.
+It greatly reduces the risk that such objects will be accidentally retained
+when they are no longer needed.  Thus space usage may be significantly reduced.
+<DT> <B> void GC_gcollect(void) </b>
+<DD>
+Explicitly force a garbage collection.
+<DT> <B> void GC_enable_incremental(void) </b>
+<DD>
+Cause the garbage collector to perform a small amount of work
+every few invocations of GC_malloc or the like, instead of performing
+an entire collection at once.  This is likely to increase total
+running time.  It will improve response on a platform that either has
+suitable support in the garbage collector (Irix and most other Unix
+versions, win32 if the collector was suitably built) or if "stubborn"
+allocation is used (see <A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gch.txt">gc.h</a>).
+On many platforms this interacts poorly with system calls 
+that write to the garbage collected heap.
+<DT> <B> GC_warn_proc GC_set_warn_proc(GC_warn_proc p) </b>
+<DD>
+Replace the default procedure used by the collector to print warnings.
+The collector
+may otherwise write to sterr, most commonly because GC_malloc was used
+in a situation in which GC_malloc_ignore_off_page would have been more
+appropriate.  See <A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gch.txt">gc.h</a> for details.
+<DT> <B> void GC_register_finalizer(...) </b>
+<DD>
+Register a function to be called when an object becomes inaccessible.
+This is often useful as a backup method for releasing system resources
+(<I>e.g.</i> closing files) when the object referencing them becomes
+inaccessible.
+It is not an acceptable method to perform actions that must be performed
+in a timely fashion.
+See <A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gch.txt">gc.h</a> for details of the interface.
+See <A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/finalization.html">here</a> for a more detailed discussion
+of the design.
+<P>
+Note that an object may become inaccessible before client code is done
+operating on its fields.  Suitable synchronization is usually required.
+See <A HREF="http://portal.acm.org/citation.cfm?doid=604131.604153">here</a>
+or <A HREF="http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html">here</a>
+for details.
+</dl>
+<P>
+If you are concerned with multiprocessor performance and scalability,
+you should consider enabling and using thread local allocation (<I>e.g.</i>
+GC_LOCAL_MALLOC, see <TT>gc_local_alloc.h</tt>.  If your platform
+supports it, you should build the collector with parallel marking support
+(-DPARALLEL_MARK, or --enable-parallel-mark).
+<P>
+If the collector is used in an environment in which pointer location
+information for heap objects is easily available, this can be passed on
+to the colllector using the interfaces in either <TT>gc_typed.h</tt>
+or <TT>gc_gcj.h</tt>.
+<P>
+The collector distribution also includes a <B>string package</b> that takes
+advantage of the collector.  For details see
+<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/cordh.txt">cord.h</a>
+
+<H1>C++ Interface</h1>
+There are three distinct ways to use the collector from C++:
+<DL>
+<DT> <B> STL allocators </b>
+<DD>
+Users of the <A HREF="http://www.sgi.com/tech/stl">SGI extended STL</a>
+can include <TT>new_gc_alloc.h</tt> before including
+STL header files.
+(<TT>gc_alloc.h</tt> corresponds to now obsolete versions of the
+SGI STL.)
+This defines SGI-style allocators
+<UL>
+<LI> alloc
+<LI> single_client_alloc
+<LI> gc_alloc
+<LI> single_client_gc_alloc
+</ul>
+which may be used either directly to allocate memory or to instantiate
+container templates.  The first two allocate uncollectable but traced
+memory, while the second two allocate collectable memory.
+The single_client versions are not safe for concurrent access by
+multiple threads, but are faster.
+<P>
+For an example, click <A HREF="http://hpl.hp.com/personal/Hans_Boehm/gc/gc_alloc_exC.txt">here</a>.
+<P>
+Recent versions of the collector also include a more standard-conforming
+allocator implemention in <TT>gc_allocator.h</tt>.  It defines
+<UL>
+<LI> traceable_allocator
+<LI> gc_allocator
+</ul>
+Again the former allocates uncollectable but traced memory.
+This should work with any fully standard-conforming C++ compiler.
+<DT> <B> Class inheritance based interface </b>
+<DD>
+Users may include gc_cpp.h and then cause members of certain classes to
+be allocated in garbage collectable memory by inheriting from class gc.
+For details see <A HREF="http://hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc_cpph.txt">gc_cpp.h</a>.
+<DT> <B> C interface </b>
+<DD>
+It is also possible to use the C interface from 
+<A HREF="http://hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gch.txt">gc.h</a> directly.
+On platforms which use malloc to implement ::new, it should usually be possible
+to use a version of the collector that has been compiled as a malloc
+replacement.  It is also possible to replace ::new and other allocation
+functions suitably.
+<P>
+Note that user-implemented small-block allocation often works poorly with
+an underlying garbage-collected large block allocator, since the collector
+has to view all objects accessible from the user's free list as reachable.
+This is likely to cause problems if GC_malloc is used with something like
+the original HP version of STL.
+This approach works with the SGI versions of the STL only if the
+<TT>malloc_alloc</tt> allocator is used.
+</dl>
+</body>
+</html>
diff --git a/doc/scale.html b/doc/scale.html
new file mode 100644 (file)
index 0000000..2e70148
--- /dev/null
@@ -0,0 +1,210 @@
+<HTML>
+<HEAD>
+<TITLE>Garbage collector scalability</TITLE>
+</HEAD>
+<BODY>
+<H1>Garbage collector scalability</h1>
+In its default configuration, the Boehm-Demers-Weiser garbage collector
+is not thread-safe.  It can be made thread-safe for a number of environments
+by building the collector with the appropriate
+<TT>-D</tt><I>XXX</i><TT>-THREADS</tt> compilation
+flag.  This has primarily two effects:
+<OL>
+<LI> It causes the garbage collector to stop all other threads when
+it needs to see a consistent memory state.
+<LI> It causes the collector to acquire a lock around essentially all
+allocation and garbage collection activity.
+</ol>
+Since a single lock is used for all allocation-related activity, only one
+thread can be allocating or collecting at one point.  This inherently
+limits performance of multi-threaded applications on multiprocessors.
+<P>
+On most platforms, the allocator/collector lock is implemented as a
+spin lock with exponential back-off.  Longer wait times are implemented
+by yielding and/or sleeping.  If a collection is in progress, the pure
+spinning stage is skipped.  This has the advantage that uncontested and
+thus most uniprocessor lock acquisitions are very cheap.  It has the
+disadvantage that the application may sleep for small periods of time
+even when there is work to be done.  And threads may be unnecessarily
+woken up for short periods.  Nonetheless, this scheme empirically
+outperforms native queue-based mutual exclusion implementations in most
+cases, sometimes drastically so.
+<H2>Options for enhanced scalability</h2>
+Version 6.0 of the collector adds two facilities to enhance collector
+scalability on multiprocessors.  As of 6.0alpha1, these are supported 
+only under Linux on X86 and IA64 processors, though ports to other
+otherwise supported Pthreads platforms should be straightforward.
+They are intended to be used together.
+<UL>
+<LI>
+Building the collector with <TT>-DPARALLEL_MARK</tt> allows the collector to
+run the mark phase in parallel in multiple threads, and thus on multiple
+processors.  The mark phase typically consumes the large majority of the
+collection time.  Thus this largely parallelizes the garbage collector
+itself, though not the allocation process.  Currently the marking is
+performed by the thread that triggered the collection, together with
+<I>N</i>-1 dedicated
+threads, where <I>N</i> is the number of processors detected by the collector.
+The dedicated threads are created once at initialization time.
+<P>
+A second effect of this flag is to switch to a more concurrent
+implementation of <TT>GC_malloc_many</tt>, so that free lists can be
+built, and memory can be cleared, by more than one thread concurrently.
+<LI>
+Building the collector with -DTHREAD_LOCAL_ALLOC adds support for thread
+local allocation.  It does not, by itself, cause thread local allocation
+to be used.  It simply allows the use of the interface in 
+<TT>gc_local_alloc.h</tt>.
+<P>
+Memory returned from thread-local allocators is completely interchangeable
+with that returned by the standard allocators.  It may be used by other
+threads.  The only difference is that, if the thread allocates enough
+memory of a certain kind, it will build a thread-local free list for
+objects of that kind, and allocate from that.  This greatly reduces
+locking.  The thread-local free lists are refilled using 
+<TT>GC_malloc_many</tt>.
+<P>
+An important side effect of this flag is to replace the default
+spin-then-sleep lock to be replace by a spin-then-queue based implementation.
+This <I>reduces performance</i> for the standard allocation functions,
+though it usually improves performance when thread-local allocation is
+used heavily, and thus the number of short-duration lock acquisitions
+is greatly reduced.
+</ul>
+<P>
+The easiest way to switch an application to thread-local allocation is to
+<OL>
+<LI> Define the macro <TT>GC_REDIRECT_TO_LOCAL</tt>,
+and then include the <TT>gc.h</tt>
+header in each client source file.
+<LI> Invoke <TT>GC_thr_init()</tt> before any allocation.
+<LI> Allocate using <TT>GC_MALLOC</tt>, <TT>GC_MALLOC_ATOMIC</tt>,
+and/or <TT>GC_GCJ_MALLOC</tt>.
+</ol>
+<H2>The Parallel Marking Algorithm</h2>
+We use an algorithm similar to
+<A HREF="http://www.yl.is.s.u-tokyo.ac.jp/gc/">that developed by
+Endo, Taura, and Yonezawa</a> at the University of Tokyo.
+However, the data structures and implementation are different,
+and represent a smaller change to the original collector source,
+probably at the expense of extreme scalability.  Some of
+the refinements they suggest, <I>e.g.</i> splitting large
+objects, were also incorporated into out approach.
+<P>
+The global mark stack is transformed into a global work queue.
+Unlike the usual case, it never shrinks during a mark phase.
+The mark threads remove objects from the queue by copying them to a
+local mark stack and changing the global descriptor to zero, indicating
+that there is no more work to be done for this entry.
+This removal
+is done with no synchronization.  Thus it is possible for more than
+one worker to remove the same entry, resulting in some work duplication.
+<P>
+The global work queue grows only if a marker thread decides to
+return some of its local mark stack to the global one.  This
+is done if the global queue appears to be running low, or if
+the local stack is in danger of overflowing.  It does require
+synchronization, but should be relatively rare.
+<P>
+The sequential marking code is reused to process local mark stacks.
+Hence the amount of additional code required for parallel marking
+is minimal.
+<P>
+It should be possible to use generational collection in the presence of the
+parallel collector, by calling <TT>GC_enable_incremental()</tt>.
+This does not result in fully incremental collection, since parallel mark
+phases cannot currently be interrupted, and doing so may be too
+expensive.
+<P>
+Gcj-style mark descriptors do not currently mix with the combination
+of local allocation and incremental collection.  They should work correctly
+with one or the other, but not both.
+<P>
+The number of marker threads is set on startup to the number of
+available processors (or to the value of the <TT>GC_NPROCS</tt>
+environment variable).  If only a single processor is detected,
+parallel marking is disabled.
+<P>
+Note that setting GC_NPROCS to 1 also causes some lock acquisitions inside
+the collector to immediately yield the processor instead of busy waiting
+first.  In the case of a multiprocessor and a client with multiple
+simultaneously runnable threads, this may have disastrous performance
+consequences (e.g. a factor of 10 slowdown). 
+<H2>Performance</h2>
+We conducted some simple experiments with a version of
+<A HREF="gc_bench.html">our GC benchmark</a> that was slightly modified to
+run multiple concurrent client threads in the same address space.
+Each client thread does the same work as the original benchmark, but they share
+a heap.
+This benchmark involves very little work outside of memory allocation.
+This was run with GC 6.0alpha3 on a dual processor Pentium III/500 machine
+under Linux 2.2.12.
+<P>
+Running with a thread-unsafe collector,  the benchmark ran in 9
+seconds.  With the simple thread-safe collector,
+built with <TT>-DLINUX_THREADS</tt>, the execution time
+increased to 10.3 seconds, or 23.5 elapsed seconds with two clients.
+(The times for the <TT>malloc</tt>/i<TT>free</tt> version
+with glibc <TT>malloc</tt>
+are 10.51 (standard library, pthreads not linked),
+20.90 (one thread, pthreads linked),
+and 24.55 seconds respectively. The benchmark favors a
+garbage collector, since most objects are small.)
+<P>
+The following table gives execution times for the collector built
+with parallel marking and thread-local allocation support
+(<TT>-DGC_LINUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC</tt>).  We tested
+the client using either one or two marker threads, and running
+one or two client threads.  Note that the client uses thread local
+allocation exclusively.  With -DTHREAD_LOCAL_ALLOC the collector
+switches to a locking strategy that is better tuned to less frequent
+lock acquisition.  The standard allocation primitives thus peform
+slightly worse than without -DTHREAD_LOCAL_ALLOC, and should be
+avoided in time-critical code.
+<P>
+(The results using <TT>pthread_mutex_lock</tt>
+directly for allocation locking would have been worse still, at
+least for older versions of linuxthreads.
+With THREAD_LOCAL_ALLOC, we first repeatedly try to acquire the
+lock with pthread_mutex_try_lock(), busy_waiting between attempts.
+After a fixed number of attempts, we use pthread_mutex_lock().)
+<P>
+These measurements do not use incremental collection, nor was prefetching
+enabled in the marker.  We used the C version of the benchmark.
+All measurements are in elapsed seconds on an unloaded machine.
+<P>
+<TABLE BORDER ALIGN="CENTER">
+<TR><TH>Number of threads</th><TH>1 marker thread (secs.)</th>
+<TH>2 marker threads (secs.)</th></tr>
+<TR><TD>1 client</td><TD ALIGN="CENTER">10.45</td><TD ALIGN="CENTER">7.85</td>
+<TR><TD>2 clients</td><TD ALIGN="CENTER">19.95</td><TD ALIGN="CENTER">12.3</td>
+</table>
+<PP>
+The execution time for the single threaded case is slightly worse than with
+simple locking.  However, even the single-threaded benchmark runs faster than
+even the thread-unsafe version if a second processor is available.
+The execution time for two clients with thread local allocation time is
+only 1.4 times the sequential execution time for a single thread in a
+thread-unsafe environment, even though it involves twice the client work.
+That represents close to a
+factor of 2 improvement over the 2 client case with the old collector.
+The old collector clearly
+still suffered from some contention overhead, in spite of the fact that the
+locking scheme had been fairly well tuned.
+<P>
+Full linear speedup (i.e. the same execution time for 1 client on one
+processor as 2 clients on 2 processors)
+is probably not achievable on this kind of
+hardware even with such a small number of processors,
+since the memory system is
+a major constraint for the garbage collector,
+the processors usually share a single memory bus, and thus
+the aggregate memory bandwidth does not increase in
+proportion to the number of processors. 
+<P>
+These results are likely to be very sensitive to both hardware and OS
+issues.  Preliminary experiments with an older Pentium Pro machine running
+an older kernel were far less encouraging.
+
+</body>
+</html>
index 89c515da76577e6b2d0b866e71389c7435ee035a..c46a281cc6751195db7fe163285c60a1999836b1 100644 (file)
@@ -1,13 +1,14 @@
 <HTML>
 <HEAD>
     <TITLE>  Two-Level Tree Structure for Fast Pointer Lookup</TITLE>
-    <AUTHOR> Hans-J. Boehm, Silicon Graphics</author>
+    <AUTHOR> Hans-J. Boehm, Silicon Graphics (now at HP)</author>
 </HEAD>
 <BODY>
 <H1>Two-Level Tree Structure for Fast Pointer Lookup</h1>
 <P>
 The conservative garbage collector described
-<A HREF="gc.html">here</a> uses a 2-level tree
+<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">here</a>
+uses a 2-level tree
 data structure to aid in fast pointer identification.
 This data structure is described in a bit more detail here, since
 <OL>
index b888a52630e59876137daa039ce7271734c9acef..9a530a23bf5b2105406e052e4430c190f58bf214 100644 (file)
@@ -57,7 +57,8 @@
     !defined(HPUX) && !(defined(LINUX) && defined(__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.
@@ -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      */
@@ -355,23 +322,10 @@ void GC_register_dynamic_libraries()
                /* Stack mapping; discard       */
                continue;
            }
-           if (start <= datastart && end > datastart && maj_dev != 0) {
-               /* Main data segment; discard   */
-               continue;
-           }
 #          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;
            }
@@ -381,76 +335,23 @@ void GC_register_dynamic_libraries()
            if (start >= least_ha && end <= greatest_ha) continue;
            GC_add_roots_inner((char *)start, (char *)end, TRUE);
        }
-     }
+    }
+    return 1;
 }
 
-//
-//  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
-//  
-//  For 64 bit ABIs:
-//  0       17       34            56
-//
-//  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'.)
-//
-#if CPP_WORDSZ == 32
-# define OFFSET_MAP_START   0
-# define OFFSET_MAP_END     9
-# define OFFSET_MAP_PROT   18
-# define OFFSET_MAP_MAJDEV 32
-# define ADDR_WIDTH        8
-#endif
-
-#if CPP_WORDSZ == 64
-# define OFFSET_MAP_START   0
-# define OFFSET_MAP_END    17
-# define OFFSET_MAP_PROT   34
-# define OFFSET_MAP_MAJDEV 56
-# define ADDR_WIDTH       16
-#endif
-
-static char *parse_map_entry(char *buf_ptr, word *start, word *end,
-                             char *prot_buf, unsigned int *maj_dev)
+void GC_register_dynamic_libraries()
 {
-    int i;
-    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+ADDR_WIDTH] = '\0';
-        *start = strtoul(tok, NULL, 16);
-
-        tok = buf_ptr+OFFSET_MAP_END;
-        buf_ptr[OFFSET_MAP_END+ADDR_WIDTH] = '\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');
+   if (!GC_apply_to_maps(GC_register_map_entries))
+       ABORT("Failed to read /proc for library registration.");
+}
 
-    return buf_ptr;
+/* We now take care of the main data segment ourselves: */
+GC_bool GC_register_main_static_data()
+{
+  return FALSE;
 }
+  
+# define HAVE_REGISTER_MAIN_STATIC_DATA
 
 #endif /* USE_PROC_FOR_LIBRARIES */
 
@@ -482,13 +383,6 @@ static int GC_register_dynlib_callback(info, size, ptr)
       + sizeof (info->dlpi_phnum))
     return -1;
 
-  /* Skip the first object - it is the main program.  */
-  if (*(int *)ptr == 0)
-    {
-      *(int *)ptr = 1;
-      return 0;
-    }
-
   p = info->dlpi_phdr;
   for( i = 0; i < (int)(info->dlpi_phnum); ((i++),(p++)) ) {
     switch( p->p_type ) {
@@ -504,6 +398,7 @@ static int GC_register_dynlib_callback(info, size, ptr)
     }
   }
 
+  * (int *)ptr = 1;    /* Signal that we were called */
   return 0;
 }     
 
@@ -513,16 +408,32 @@ static int GC_register_dynlib_callback(info, size, ptr)
 
 GC_bool GC_register_dynamic_libraries_dl_iterate_phdr()
 {
-  int tmp = 0;
-
   if (dl_iterate_phdr) {
-    dl_iterate_phdr(GC_register_dynlib_callback, &tmp);
+    int did_something = 0;
+    dl_iterate_phdr(GC_register_dynlib_callback, &did_something);
+    if (!did_something) {
+       /* dl_iterate_phdr may forget the static data segment in        */
+       /* statically linked executables.                               */
+       GC_add_roots_inner(DATASTART, (char *)(DATAEND), TRUE);
+#       if defined(DATASTART2)
+          GC_add_roots_inner(DATASTART2, (char *)(DATAEND2), TRUE);
+#       endif
+    }
+
     return TRUE;
   } else {
     return FALSE;
   }
 }
 
+/* Do we need to separately register the main static data segment? */
+GC_bool GC_register_main_static_data()
+{
+  return (dl_iterate_phdr == 0);
+}
+
+#define HAVE_REGISTER_MAIN_STATIC_DATA
+
 # else /* !LINUX || version(glibc) < 2.2.4 */
 
 /* Dynamic loading code for Linux running ELF. Somewhat tested on
@@ -789,10 +700,23 @@ void GC_register_dynamic_libraries()
     }
 # endif
 
-# ifndef MSWINCE
+# ifdef MSWINCE
+  /* Do we need to separately register the main static data segment? */
+  GC_bool GC_register_main_static_data()
+  {
+    return FALSE;
+  }
+# else /* win32 */
   extern GC_bool GC_no_win32_dlls;
-# endif
+
+  GC_bool GC_register_main_static_data()
+  {
+    return GC_no_win32_dlls;
+  }
+# endif /* win32 */
   
+# define HAVE_REGISTER_MAIN_STATIC_DATA
+
   void GC_register_dynamic_libraries()
   {
     MEMORY_BASIC_INFORMATION buf;
@@ -1037,7 +961,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;
@@ -1045,7 +969,122 @@ 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;
+    
+    if(initialized) return;
+    
+#   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_addres failed");
+            
+#   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 existing and all future libraries
+    */
+        
+    _dyld_register_func_for_add_image(GC_dyld_image_add);
+    _dyld_register_func_for_remove_image(GC_dyld_image_remove);
+    initialized = TRUE;
+}
+
+#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 */
 
@@ -1093,4 +1132,15 @@ void GC_register_dynamic_libraries(){}
 int GC_no_dynamic_loading;
 
 #endif /* !PCR */
+
 #endif /* !DYNAMIC_LOADING */
+
+#ifndef HAVE_REGISTER_MAIN_STATIC_DATA
+
+/* Do we need to separately register the main static data segment? */
+GC_bool GC_register_main_static_data()
+{
+  return TRUE;
+}
+#endif /* HAVE_REGISTER_MAIN_STATIC_DATA */
+
index 42890ad0e98b80698abea8cca5d2aa87812cee4d..3b9d9f5ea1ee3804cfbcd17177999c38e6cba500 100644 (file)
@@ -764,7 +764,6 @@ int GC_invoke_finalizers()
     struct finalizable_object * curr_fo;
     int count = 0;
     word mem_freed_before;
-    GC_bool first_time = TRUE;
     DCL_LOCK_STATE;
     
     while (GC_finalize_now != 0) {
@@ -772,9 +771,8 @@ int GC_invoke_finalizers()
            DISABLE_SIGNALS();
            LOCK();
 #      endif
-       if (first_time) {
+       if (count == 0) {
            mem_freed_before = GC_mem_freed;
-           first_time = FALSE;
        }
        curr_fo = GC_finalize_now;
 #      ifdef THREADS
@@ -797,7 +795,7 @@ int GC_invoke_finalizers()
            GC_free((GC_PTR)curr_fo);
 #      endif
     }
-    if (mem_freed_before != GC_mem_freed) {
+    if (count != 0 && mem_freed_before != GC_mem_freed) {
         LOCK();
        GC_finalizer_mem_freed += (GC_mem_freed - mem_freed_before);
        UNLOCK();
@@ -814,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
index eafaa2b1b46c383abfebe682fd632e959353557d..4c690edcfe49c3c923722a34349aba2bb7576978 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 fd6009e1c354a694234a187b14db8392c90261c1..3dcccf21f5a86099e809475d5cd3303c9a61f2b0 100644 (file)
--- a/if_mach.c
+++ b/if_mach.c
@@ -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");
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644 (file)
index 0000000..306026b
--- /dev/null
@@ -0,0 +1,35 @@
+# 
+# 
+# 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 headers
+#
+pkginclude_HEADERS = gc.h gc_typed.h gc_inl.h \
+    gc_inline.h gc_mark.h gc_cpp.h \
+    weakpointer.h gc_alloc.h new_gc_alloc.h \
+    gc_allocator.h gc_backptr.h \
+    gc_gcj.h gc_local_alloc.h leak_detector.h \
+    gc_amiga_redirects.h gc_pthread_redirects.h \
+    gc_config_macros.h
+
+# headers which are not installed
+#
+dist_noinst_HEADERS = private/gc_hdrs.h \
+    private/gc_priv.h private/gcconfig.h \
+    private/gc_pmark.h private/gc_locks.h \
+    private/solaris_threads.h private/dbg_mlc.h \
+    private/specific.h private/cord_pos.h \
+    private/pthread_support.h private/pthread_stop_world.h \
+    private/darwin_semaphore.h private/darwin_stop_world.h \
+    cord.h ec.h javaxfc.h 
diff --git a/include/Makefile.in b/include/Makefile.in
new file mode 100644 (file)
index 0000000..9ade270
--- /dev/null
@@ -0,0 +1,329 @@
+# 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 headers
+#
+pkginclude_HEADERS = gc.h gc_typed.h gc_inl.h \
+    gc_inline.h gc_mark.h gc_cpp.h \
+    weakpointer.h gc_alloc.h new_gc_alloc.h \
+    gc_allocator.h gc_backptr.h \
+    gc_gcj.h gc_local_alloc.h leak_detector.h \
+    gc_amiga_redirects.h gc_pthread_redirects.h \
+    gc_config_macros.h
+
+
+# headers which are not installed
+#
+dist_noinst_HEADERS = private/gc_hdrs.h \
+    private/gc_priv.h private/gcconfig.h \
+    private/gc_pmark.h private/gc_locks.h \
+    private/solaris_threads.h private/dbg_mlc.h \
+    private/specific.h private/cord_pos.h \
+    private/pthread_support.h private/pthread_stop_world.h \
+    private/darwin_semaphore.h private/darwin_stop_world.h \
+    cord.h ec.h javaxfc.h 
+
+subdir = include
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+HEADERS = $(dist_noinst_HEADERS) $(pkginclude_HEADERS)
+
+DIST_COMMON = $(dist_noinst_HEADERS) $(pkginclude_HEADERS) 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  include/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:
+pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(pkgincludedir)
+       @list='$(pkginclude_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(pkgincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(pkgincludedir)/$$f"; \
+         $(pkgincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(pkgincludedir)/$$f; \
+       done
+
+uninstall-pkgincludeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(pkginclude_HEADERS)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f $(DESTDIR)$(pkgincludedir)/$$f"; \
+         rm -f $(DESTDIR)$(pkgincludedir)/$$f; \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       $(mkinstalldirs) $(distdir)/private
+       @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 $(HEADERS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(pkgincludedir)
+
+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 \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgincludeHEADERS
+
+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-info-am uninstall-pkgincludeHEADERS
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool distclean distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-pkgincludeHEADERS install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool tags uninstall uninstall-am \
+       uninstall-info-am uninstall-pkgincludeHEADERS
+
+# 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 57d5ebd9b5960ad39b4cd8a2b7c7b40e612a3559..f3e31d986e98eee21da2fefb7f1e8e89a0acb8b2 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(DGUX_THREADS)
-# if !defined(GC_DGUX386_THREADS)
-#  define GC_DGUX386_THREADS
-# endif
-#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_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
-# define _POSIX4A_DRAFT10_SOURCE 1
-#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) || \
-       defined(GC_DGUX386_THREADS) || \
-        (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
-#   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
@@ -226,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 7.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 */
@@ -430,17 +341,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));
 
@@ -475,9 +390,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_diable() 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          */
@@ -533,6 +457,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
@@ -551,6 +511,10 @@ 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,
@@ -577,8 +541,12 @@ GC_API GC_PTR GC_debug_realloc_replacement
 # 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) \
@@ -597,6 +565,10 @@ GC_API GC_PTR GC_debug_realloc_replacement
 #   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) \
@@ -749,11 +721,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));
 
@@ -770,6 +737,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     */
@@ -905,9 +876,8 @@ 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>
-# include <winbase.h>
 
   /*
    * All threads must be created using GC_CreateThread, so that they will be
@@ -916,7 +886,7 @@ extern void GC_thr_init();  /* Needed for Solaris/X86       */
    * 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 );
@@ -938,7 +908,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
@@ -950,14 +920,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 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
 
diff --git a/include/gc_config_macros.h b/include/gc_config_macros.h
new file mode 100644 (file)
index 0000000..0c836d8
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * This should never be included directly.  It is included only from gc.h.
+ * We separate it only to make gc.h more suitable as documentation.
+ * 
+ * Some tests for old macros.  These violate our namespace rules and will
+ * disappear shortly.  Use the GC_ names.
+ */
+#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS)
+# define GC_SOLARIS_THREADS
+#endif
+#if defined(_SOLARIS_PTHREADS)
+# define GC_SOLARIS_PTHREADS
+#endif
+#if defined(IRIX_THREADS)
+# define GC_IRIX_THREADS
+#endif
+#if defined(DGUX_THREADS)
+# if !defined(GC_DGUX386_THREADS)
+#  define GC_DGUX386_THREADS
+# endif
+#endif
+#if defined(AIX_THREADS)
+# define GC_AIX_THREADS
+#endif
+#if defined(HPUX_THREADS)
+# define GC_HPUX_THREADS
+#endif
+#if defined(OSF1_THREADS)
+# define GC_OSF1_THREADS
+#endif
+#if defined(LINUX_THREADS)
+# define GC_LINUX_THREADS
+#endif
+#if defined(WIN32_THREADS)
+# define GC_WIN32_THREADS
+#endif
+#if defined(USE_LD_WRAP)
+# define GC_USE_LD_WRAP
+#endif
+
+#if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \
+                            || defined(GC_SOLARIS_PTHREADS) \
+                            || defined(GC_HPUX_THREADS) \
+                            || defined(GC_AIX_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_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
+# define _POSIX4A_DRAFT10_SOURCE 1
+#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) || \
+       defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \
+       defined(GC_AIX_THREADS) || \
+        (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
+#   define GC_PTHREADS
+# endif
+
+#if defined(GC_THREADS) && !defined(GC_PTHREADS)
+# if defined(__linux__)
+#   define GC_LINUX_THREADS
+#   define GC_PTHREADS
+# endif
+# if !defined(LINUX) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
+                         || defined(hppa) || defined(__HPPA))
+#   define GC_HPUX_THREADS
+#   define GC_PTHREADS
+# endif
+# if !defined(__linux__) && (defined(__alpha) || defined(__alpha__))
+#   define GC_OSF1_THREADS
+#   define GC_PTHREADS
+# endif
+# if defined(__mips) && !defined(__linux__)
+#   define GC_IRIX_THREADS
+#   define GC_PTHREADS
+# endif
+# if defined(__sparc) && !defined(__linux__)
+#   define GC_SOLARIS_PTHREADS
+#   define GC_PTHREADS
+# endif
+# if defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
+#   define GC_DARWIN_THREADS
+#   define GC_PTHREADS
+# endif
+# if !defined(GC_PTHREADS) && defined(__FreeBSD__)
+#   define GC_FREEBSD_THREADS
+#   define GC_PTHREADS
+# endif
+# if defined(DGUX) && (defined(i386) || defined(__i386__))
+#   define GC_DGUX386_THREADS
+#   define GC_PTHREADS
+# endif
+#endif /* GC_THREADS */
+
+#if defined(GC_THREADS) && !defined(GC_PTHREADS) && defined(MSWIN32)
+# define GC_WIN32_THREADS
+#endif
+
+#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
+#   define GC_SOLARIS_THREADS
+#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(_DLL) && !defined(GC_NOT_DLL) && !defined(GC_DLL)
+# define GC_DLL
+#endif
+
+#if defined(__MINGW32__) && defined(GC_DLL)
+# ifdef GC_BUILD
+#   define GC_API __declspec(dllexport)
+# else
+#   define GC_API __declspec(dllimport)
+# endif
+#endif
+
+#if (defined(__DMC__) || defined(_MSC_VER)) && 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
+
index 990035b9d39bfee9ec8301d77602b07f0bb0f73c..d789a3731e33a7ef5b7b1271776ac566c27b6e4b 100644 (file)
@@ -165,14 +165,18 @@ class gc {public:
        /* Must be redefined here, since the other overloadings */
        /* hide the global definition.                          */
     inline void operator delete( void* obj );
-    inline void operator delete( void*, void* );
+#   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 );
-    inline void gc::operator delete[]( void*, void* );
+#   ifndef __BORLANDC__
+      inline void gc::operator delete[]( void*, void* );
+#   endif
 #endif /* GC_OPERATOR_NEW_ARRAY */
     };    
     /*
@@ -278,7 +282,9 @@ inline void* gc::operator new( size_t size, void *p ) {
 inline void gc::operator delete( void* obj ) {
     GC_FREE( obj );}
     
-inline void gc::operator delete( void*, void* ) {}
+#ifndef __BORLANDC__
+  inline void gc::operator delete( void*, void* ) {}
+#endif
 
 #ifdef GC_OPERATOR_NEW_ARRAY
 
@@ -294,13 +300,15 @@ inline void* gc::operator new[]( size_t size, void *p ) {
 inline void gc::operator delete[]( void* obj ) {
     gc::operator delete( obj );}
 
-inline void gc::operator delete[]( void*, void* ) {}
+#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 0856d16fdaeb67f7bf5d6acb6878f6b51a65ae79..9ddba2ca527464f9deb155babb5a73766184f643 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 47284fbc97a65673c5818e652b6fab81bad65f23..99a3e8da6404601828184feffcadedbd7d1835b1 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);
 
 # define pthread_create GC_pthread_create
+#ifndef GC_DARWIN_THREADS
 # define pthread_sigmask GC_pthread_sigmask
+#endif
 # define pthread_join GC_pthread_join
 # define pthread_detach GC_pthread_detach
+#ifndef GC_DARWIN_THREADS
 # define dlopen GC_dlopen
+#endif
 
 #endif /* GC_xxxxx_THREADS */
 
index 2e0598f204c71fa11ede4f2322d8de31dbd5b841..905734b8da0f550c3833c8dd21f09b7c23828bb2 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 */
 
diff --git a/include/private/darwin_semaphore.h b/include/private/darwin_semaphore.h
new file mode 100644 (file)
index 0000000..0f43982
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef GC_DARWIN_SEMAPHORE_H
+#define GC_DARWIN_SEMAPHORE_H
+
+#if !defined(GC_DARWIN_THREADS)
+#error darwin_semaphore.h included with GC_DARWIN_THREADS not defined
+#endif
+
+/*
+   This is a very simple semaphore implementation for darwin. It
+   is implemented in terms of pthreads calls so it isn't async signal
+   safe. This isn't a problem because signals aren't used to
+   suspend threads on darwin.
+*/
+   
+typedef struct {
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    int value;
+} sem_t;
+
+static int sem_init(sem_t *sem, int pshared, int value) {
+    int ret;
+    if(pshared)
+        GC_abort("sem_init with pshared set");
+    sem->value = value;
+    
+    ret = pthread_mutex_init(&sem->mutex,NULL);
+    if(ret < 0) return -1;
+    ret = pthread_cond_init(&sem->cond,NULL);
+    if(ret < 0) return -1;
+    return 0;
+}
+
+static int sem_post(sem_t *sem) {
+    if(pthread_mutex_lock(&sem->mutex) < 0)
+        return -1;
+    sem->value++;
+    if(pthread_cond_signal(&sem->cond) < 0) {
+        pthread_mutex_unlock(&sem->mutex);
+        return -1;
+    }
+    if(pthread_mutex_unlock(&sem->mutex) < 0)
+        return -1;
+    return 0;
+}
+
+static int sem_wait(sem_t *sem) {
+    if(pthread_mutex_lock(&sem->mutex) < 0)
+        return -1;
+    while(sem->value == 0) {
+        pthread_cond_wait(&sem->cond,&sem->mutex);
+    }
+    sem->value--;
+    if(pthread_mutex_unlock(&sem->mutex) < 0)
+        return -1;    
+    return 0;
+}
+
+static int sem_destroy(sem_t *sem) {
+    int ret;
+    ret = pthread_cond_destroy(&sem->cond);
+    if(ret < 0) return -1;
+    ret = pthread_mutex_destroy(&sem->mutex);
+    if(ret < 0) return -1;
+    return 0;
+}
+
+#endif
diff --git a/include/private/darwin_stop_world.h b/include/private/darwin_stop_world.h
new file mode 100644 (file)
index 0000000..9924297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef GC_DARWIN_STOP_WORLD_H
+#define GC_DARWIN_STOP_WORLD_H
+
+#if !defined(GC_DARWIN_THREADS)
+#error darwin_stop_world.h included without GC_DARWIN_THREADS defined
+#endif
+
+#include <mach/mach.h>
+#include <mach/thread_act.h>
+
+struct thread_stop_info {
+    mach_port_t mach_thread;
+};
+
+#endif
index 6133343a87f3f3ca63d093310ad9df0b0faefa84..250760516309325c239eeb821d76f7f97cab4c68 100644 (file)
                "\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) {
         }
 #       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;
+       }
+#    endif
 #  endif /* __GNUC__ */
 #  if (defined(ALPHA) && !defined(__GNUC__))
 #    ifndef OSF1
 #    elif __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
        || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
 #       ifdef __GNUC__
-#          define GC_test_and_set(addr) _test_and_set(addr,1)
+#          define GC_test_and_set(addr) _test_and_set((void *)addr,1)
 #       else
-#          define GC_test_and_set(addr) test_and_set(addr,1)
+#          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 */
          {
           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 */
          __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,
 #       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;
+         }
+#      endif
+#     endif
 #     if !defined(GENERIC_COMPARE_AND_SWAP)
         /* Returns the original value of *addr.        */
         inline static GC_word GC_atomic_add(volatile GC_word *addr,
                { 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.                        */
index cf85d4de72372fdd90da3551ecc71cc630cba239..c109738203a2c74e33563d7e1f9a310c7ecfe366 100644 (file)
@@ -281,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 cc36317af47c13b73f67cfef2473794415a37fac..eb477c03ffea8034a31910169fe609d81f77c6a8 100644 (file)
@@ -42,8 +42,8 @@
 #   include <sys/resource.h>
 #endif /* BSD_TIME */
 
-# ifndef GC_H
-#   include "gc.h"
+# ifndef _GC_H
+#   include "../gc.h"
 # endif
 
 # ifndef GC_MARK_H
@@ -352,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
 
@@ -905,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]
@@ -1180,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))
@@ -1353,6 +1358,11 @@ extern void (*GC_start_call_back) GC_PROTO((void));
   void GC_generic_push_regs GC_PROTO((ptr_t cold_gc_frame));
 # 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      */
@@ -1403,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?                                       */
@@ -1413,6 +1424,11 @@ 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.                        */
   
 /* Machine dependent startup routines */
 ptr_t GC_get_stack_base GC_PROTO((void));      /* Cold end of stack */
@@ -1613,6 +1629,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));
@@ -1642,6 +1660,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.    */
@@ -1664,6 +1688,10 @@ 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          */
@@ -1831,6 +1859,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                */
index e6cf91e505877a703a5033e9203c47938255bc72..43e66258bee839cd7b52e18b778f770dc5e37e73 100644 (file)
 
 # 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.                                       */
 
@@ -33,7 +39,9 @@
 
 /* First a unified test for Linux: */
 # if defined(linux) || defined(__linux__)
+#  ifndef LINUX
 #    define LINUX
+#  endif
 # endif
 
 /* And one for NetBSD: */
 #    define ARM32
 #    define mach_type_known
 # endif
-# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__))
+# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || defined(powerpc64) || defined(__powerpc64__))
 #    define POWERPC
 #    define mach_type_known
 # endif
 # 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 mach_type_known
 # endif
 # if defined(__s390__) && defined(LINUX)
-#    define S370
+#    define S390
 #    define mach_type_known
 # endif
 # if defined(__GNU__)
                    /*                  (CX_UX and DGUX)                */
                    /*             S370       ==> 370-like machine      */
                    /*                  running Amdahl UTS4             */
-                   /*                  or a 390 running LINUX          */
+                    /*             S390       ==> 390-like machine      */
+                   /*                  running LINUX                   */
                    /*             ARM32      ==> Intel StrongARM       */
                    /*             IA64       ==> Intel IPF             */
                    /*                            (e.g. Itanium)        */
                    /*             SH         ==> Hitachi SuperH        */
                    /*                  (LINUX & MSWINCE)               */
                    /*             X86_64     ==> AMD x86-64            */
+                   /*             POWERPC    ==> IBM/Apple PowerPC     */
+                   /*                  (MACOS(<=9),DARWIN(incl.MACOSX),*/
+                   /*                   LINUX, NETBSD, NOSYS variants) */
 
 
 /*
 #   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
 #     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 HEURISTIC1
+      /* HEURISTIC1 has been reliably reported to fail for a 32-bit    */
+      /* executable on a 64 bit kernel.                                        */
+#     define LINUX_STACKBOTTOM
 #     define DYNAMIC_LOADING
-#     undef STACK_GRAN
-#     define STACK_GRAN 0x10000000
-       /* Stack usually starts at 0x80000000 */
 #     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 */
+#     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 (ptr_t)GC_SysVGetDataStart(0x100000, _etext)
+#      define DATASTART GC_SysVGetDataStart(0x100000, _etext)
        /* libc_stack_end is not set reliably for sparc64 */
 #       define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
 #     else
-#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
+#       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
 #      define LINUX_STACKBOTTOM
 #     endif
 #   endif
 #   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,      */
 #   ifdef DGUX
 #      define OS_TYPE "DGUX"
        extern int _etext, _end;
-       extern char * GC_SysVGetDataStart();
+       extern ptr_t GC_SysVGetDataStart();
 #      define DATASTART GC_SysVGetDataStart(0x1000, &_etext)
 #      define DATAEND (&_end)
 #      define STACK_GROWS_DOWN
        /*      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
 #          define DYNAMIC_LOADING
 #      endif
        extern char etext[];
-#      define DATASTART ((ptr_t)(etext))
+       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
-#     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 4 || __GLIBC__ > 2
+#     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
 #        define LINUX_STACKBOTTOM
 #     else
 #        define STACKBOTTOM 0x80000000
                              /* 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)
 
 # 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 0x1000000000000000
+#     define STACKBOTTOM ((ptr_t)0x1000000000000000)
 #   else
 #     define ALIGNMENT 4
 #     define CPP_WORDSZ 32
 #     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))
 #   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
         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
+# endif
+
+# ifdef S390
+#   define MACH_TYPE "S390"
+#   define USE_GENERIC_PUSH_REGS
+#   ifndef __s390x__
+#   define ALIGNMENT 4
+#   define CPP_WORDSZ 32
+#   else
+#   define ALIGNMENT 8
+#   define CPP_WORDSZ 64
+#   define HBLKSIZE 4096
+#   endif
 #   ifdef LINUX
 #       define OS_TYPE "LINUX"
-#       define HEURISTIC1
+#       define LINUX_STACKBOTTOM
 #       define DYNAMIC_LOADING
         extern int __data_start[];
 #       define DATASTART ((ptr_t)(__data_start))
+    extern int _end[];
+#   define DATAEND (_end)
+#   define CACHE_LINE_SIZE 256
+#   define GETPAGESIZE() 4096
 #   endif
 # endif
 
 #   define MACH_TYPE "X86_64"
 #   define ALIGNMENT 8
 #   define CPP_WORDSZ 64
+#   ifndef HBLKSIZE
+#     define HBLKSIZE 4096
+#   endif
 #   define CACHE_LINE_SIZE 64
 #   define USE_GENERIC_PUSH_REGS
 #   ifdef LINUX
 # endif
 
 # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \
-           || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) || defined(DGUX) \
-           || defined(BSD) || defined(AIX) || defined(MACOSX) || defined(OSF1)
+           || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
+           || defined(DGUX) || defined(BSD) \
+           || defined(_AIX) || defined(DARWIN) || defined(OSF1)
 #   define UNIX_LIKE   /* Basic Unix-like system calls work.   */
 # endif
 
 #   define CACHE_LINE_SIZE 32  /* Wild guess   */
 # endif
 
-# if defined(SEARCH_FOR_DATA_START) && defined(GC_PRIVATE_H)
+# ifdef LINUX
+#   define REGISTER_LIBRARIES_EARLY
+    /* We sometimes use dl_iterate_phdr, which may acquire an internal */
+    /* lock.  This isn't safe after the world has stopped.  So we must */
+    /* call GC_register_dynamic_libraries before stopping the world.   */
+    /* For performance reasons, this may be beneficial on other                */
+    /* platforms as well, though it should be avoided in win32.                */
+# endif /* LINUX */
+
+# if defined(SEARCH_FOR_DATA_START)
     extern ptr_t GC_data_start;
 #   define DATASTART GC_data_start
 # endif
 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
        --> inconsistent configuration
 # endif
+# if defined(GC_AIX_THREADS) && !defined(_AIX)
+       --> inconsistent configuration
+# endif
 # if defined(GC_WIN32_THREADS) && !defined(MSWIN32) && !defined(CYGWIN32)
        --> inconsistent configuration
 # endif
 #   define THREADS
 # endif
 
-# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \
+# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \
             || defined(LINT) || defined(MSWINCE) || defined(ARM32) \
             || (defined(I386) && defined(__LCC__))
-               /* Use setjmp based hack to mark from callee-save registers.    */
-               /* The define should move to the individual platform            */
-               /* descriptions.                                                */
+       /* Use setjmp based hack to mark from callee-save registers.    */
+       /* The define should move to the individual platform            */
+       /* descriptions.                                                */
 #      define USE_GENERIC_PUSH_REGS
 # endif
 
 # if defined(SPARC)
 #   define ASM_CLEAR_CODE      /* Stack clearing is crucial, and we    */
-                                       /* include assembly code to do it well. */
+                               /* include assembly code to do it well. */
 # endif
 
-       /* Can we save call chain in objects for debugging?                     */
-       /* SET NFRAMES (# of saved frames) and NARGS (#of args for each frame)  */
-       /* to reasonable values for the platform.                               */
-       /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified at  */
-       /* build time, though we feel free to adjust it slightly.               */
-       /* Define NEED_CALLINFO if we either save the call stack or             */
-       /* GC_ADD_CALLER is defined.                                            */
-#ifdef LINUX
-# include <features.h>
-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2
-#   define HAVE_BUILTIN_BACKTRACE
-# endif
-#endif
+  /* Can we save call chain in objects for debugging?                  */
+  /* SET NFRAMES (# of saved frames) and NARGS (#of args for each      */
+  /* frame) to reasonable values for the platform.                     */
+  /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified  */
+  /* at build time, though we feel free to adjust it slightly.         */
+  /* Define NEED_CALLINFO if we either save the call stack or          */
+  /* GC_ADD_CALLER is defined.                                         */
+  /* GC_CAN_SAVE_CALL_STACKS is set in gc.h.                           */
 
 #if defined(SPARC)
-# define CAN_SAVE_CALL_STACKS
 # define CAN_SAVE_CALL_ARGS
 #endif
 #if (defined(I386) || defined(X86_64)) && defined(LINUX)
            /* SAVE_CALL_CHAIN is supported if the code is compiled to save     */
            /* frame pointers by default, i.e. no -fomit-frame-pointer flag.    */
-# define CAN_SAVE_CALL_STACKS
 # define CAN_SAVE_CALL_ARGS
 #endif
-#if defined(HAVE_BUILTIN_BACKTRACE) && !defined(CAN_SAVE_CALL_STACKS)
-# define CAN_SAVE_CALL_STACKS
-#endif
 
 # if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
-            && defined(CAN_SAVE_CALL_STACKS)
+            && defined(GC_CAN_SAVE_CALL_STACKS)
 #   define SAVE_CALL_CHAIN 
 # endif
 # ifdef SAVE_CALL_CHAIN
 #   define DBG_HDRS_ALL
 # endif
 
+# if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
+#   define POINTER_SHIFT 0
+# endif
+
+# if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
+#   define POINTER_MASK ((GC_word)(-1))
+# endif
+
+# if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
+#   define FIXUP_POINTER(p) (p) = ((p) & (POINTER_MASK) << POINTER_SHIFT)
+# endif
+
+# if defined(FIXUP_POINTER)
+#   define NEED_FIXUP_POINTER 1
+# else
+#   define NEED_FIXUP_POINTER 0
+#   define FIXUP_POINTER(p)
+# endif
+
 #ifdef GC_PRIVATE_H
        /* This relies on some type definitions from gc_priv.h, from    */
         /* where it's normally included.                               */
                                            + GC_page_size) \
                                            + GC_page_size-1)
 #   else
-#     if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
+#     if defined(NEXT) || defined(DOS4GW) || \
                 (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
                 (defined(SUNOS5) && !defined(USE_MMAP))
 #       define GET_MEM(bytes) HBLKPTR((size_t) \
                                              + GC_page_size-1)
 #     else
 #      ifdef MSWIN32
-#        ifdef GC_PRIVATE_H
-                 extern ptr_t GC_win32_get_mem();
-#        endif
+         extern ptr_t GC_win32_get_mem();
 #         define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
 #      else
 #        ifdef MACOS
 #          endif
 #        else
 #          ifdef MSWINCE
-#            ifdef GC_PRIVATE_H
-               extern ptr_t GC_wince_get_mem();
-#            endif
+             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)
                          GC_amiga_get_mem((size_t)bytes + GC_page_size) \
                          + GC_page_size-1)
 #            else
-#              ifdef GC_PRIVATE_H
-                 extern ptr_t GC_unix_get_mem();
-#              endif
+               extern ptr_t GC_unix_get_mem();
 #               define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
 #            endif
 #          endif
diff --git a/include/private/pthread_stop_world.h b/include/private/pthread_stop_world.h
new file mode 100644 (file)
index 0000000..054c7a0
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef GC_PTHREAD_STOP_WORLD_H
+#define GC_PTHREAD_STOP_WORLD_H
+
+struct thread_stop_info {
+    int        signal;
+    word last_stop_count;      /* GC_last_stop_count value when thread */
+                               /* last successfully handled a suspend  */
+                               /* signal.                              */
+    ptr_t stack_ptr;           /* Valid only when stopped.             */
+};
+    
+#endif
diff --git a/include/private/pthread_support.h b/include/private/pthread_support.h
new file mode 100644 (file)
index 0000000..0ef917e
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef GC_PTHREAD_SUPPORT_H
+#define GC_PTHREAD_SUPPORT_H
+
+# include "private/gc_priv.h"
+
+# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+     && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
+     
+#if defined(GC_DARWIN_THREADS)
+# include "private/darwin_stop_world.h"
+#else
+# include "private/pthread_stop_world.h"
+#endif
+
+/* We use the allocation lock to protect thread-related data structures. */
+
+/* The set of all known threads.  We intercept thread creation and     */
+/* joins.                                                              */
+/* Protected by allocation/GC lock.                                    */
+/* Some of this should be declared volatile, but that's inconsistent   */
+/* with some library routine declarations.                             */
+typedef struct GC_Thread_Rep {
+    struct GC_Thread_Rep * next;  /* More recently allocated threads   */
+                                 /* with a given pthread id come       */
+                                 /* first.  (All but the first are     */
+                                 /* guaranteed to be dead, but we may  */
+                                 /* not yet have registered the join.) */
+    pthread_t id;
+    /* Extra bookkeeping information the stopping code uses */
+    struct thread_stop_info stop_info;
+    
+    short flags;
+#      define FINISHED 1       /* Thread has exited.   */
+#      define DETACHED 2       /* Thread is intended to be detached.   */
+#      define MAIN_THREAD 4    /* True for the original thread only.   */
+    short thread_blocked;      /* Protected by GC lock.                */
+                               /* Treated as a boolean value.  If set, */
+                               /* thread will acquire GC lock before   */
+                               /* doing any pointer manipulations, and */
+                               /* has set its sp value.  Thus it does  */
+                               /* not need to be sent a signal to stop */
+                               /* it.                                  */
+    ptr_t stack_end;           /* Cold end of the stack.               */
+#   ifdef IA64
+       ptr_t backing_store_end;
+       ptr_t backing_store_ptr;
+#   endif
+    void * status;             /* The value returned from the thread.  */
+                               /* Used only to avoid premature         */
+                               /* reclamation of any data it might     */
+                               /* reference.                           */
+#   ifdef THREAD_LOCAL_ALLOC
+#      if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
+#          define GRANULARITY 16
+#          define NFREELISTS 49
+#      else
+#          define GRANULARITY 8
+#          define NFREELISTS 65
+#      endif
+       /* The ith free list corresponds to size i*GRANULARITY */
+#      define INDEX_FROM_BYTES(n) ((ADD_SLOP(n) + GRANULARITY - 1)/GRANULARITY)
+#      define BYTES_FROM_INDEX(i) ((i) * GRANULARITY - EXTRA_BYTES)
+#      define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= \
+                                   (NFREELISTS-1)*GRANULARITY)
+       ptr_t ptrfree_freelists[NFREELISTS];
+       ptr_t normal_freelists[NFREELISTS];
+#      ifdef GC_GCJ_SUPPORT
+         ptr_t gcj_freelists[NFREELISTS];
+#      endif
+               /* Free lists contain either a pointer or a small count */
+               /* reflecting the number of granules allocated at that  */
+               /* size.                                                */
+               /* 0 ==> thread-local allocation in use, free list      */
+               /*       empty.                                         */
+               /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
+               /*       too few objects of this size have been         */
+               /*       allocated by this thread.                      */
+               /* >= HBLKSIZE  => pointer to nonempty free list.       */
+               /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to      */
+               /*    local alloc, equivalent to 0.                     */
+#      define DIRECT_GRANULES (HBLKSIZE/GRANULARITY)
+               /* Don't use local free lists for up to this much       */
+               /* allocation.                                          */
+#   endif
+} * GC_thread;
+
+# define THREAD_TABLE_SZ 128   /* Must be power of 2   */
+extern volatile GC_thread GC_threads[THREAD_TABLE_SZ];
+
+extern GC_bool GC_thr_initialized;
+
+GC_thread GC_lookup_thread(pthread_t id);
+
+void GC_stop_init();
+
+#endif /* GC_PTHREADS && !GC_SOLARIS_THREADS.... etc */
+#endif /* GC_PTHREAD_SUPPORT_H */
index 399f84f58d6ae25ca51edf4fc26c70743bde91bf..d04e19f5a4b5dcd9c60f66a24d7ff7e626402250 100644 (file)
@@ -85,7 +85,7 @@ static __inline__ void * PREFIXED(getspecific) (tsd * key) {
     unsigned hash_val = CACHE_HASH(qtid);
     tse * volatile * entry_ptr = key -> cache + hash_val;
     tse * entry = *entry_ptr;   /* Must be loaded only once.   */
-    if (entry -> qtid == qtid) {
+    if (EXPECT(entry -> qtid == qtid, 1)) {
       GC_ASSERT(entry -> thread == pthread_self());
       return entry -> value;
     }
index 4a66d5d1f8df306c9da8d9aa6d320fb0498e744e..3dc5f0b27b9ab556738a3c10d53bf18c839073b0 100644 (file)
@@ -74,7 +74,8 @@ asm static void PushMacRegisters()
 /* on your architecture.  Run the test_setjmp program to see whether    */
 /* there is any chance it will work.                                    */
 
-#ifndef USE_GENERIC_PUSH_REGS
+#if !defined(USE_GENERIC_PUSH_REGS) && !defined(USE_ASM_PUSH_REGS)
+#undef HAVE_PUSH_REGS
 void GC_push_regs()
 {
 #       ifdef RT
@@ -91,6 +92,7 @@ void GC_push_regs()
          asm("pushl r8");      asm("calls $1,_GC_push_one");
          asm("pushl r7");      asm("calls $1,_GC_push_one");
          asm("pushl r6");      asm("calls $1,_GC_push_one");
+#        define HAVE_PUSH_REGS
 #       endif
 #       if defined(M68K) && (defined(SUNOS4) || defined(NEXT))
        /*  M68K SUNOS - could be replaced by generic code */
@@ -113,6 +115,7 @@ void GC_push_regs()
          asm("movl d7,sp@");   asm("jbsr _GC_push_one");
 
          asm("addqw #0x4,sp");         /* put stack back where it was  */
+#        define HAVE_PUSH_REGS
 #       endif
 
 #       if defined(M68K) && defined(HP)
@@ -135,6 +138,7 @@ void GC_push_regs()
          asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one");
 
          asm("addq.w &0x4,%sp");       /* put stack back where it was  */
+#        define HAVE_PUSH_REGS
 #       endif /* M68K HP */
 
 #      if defined(M68K) && defined(AMIGA)
@@ -158,6 +162,7 @@ void GC_push_regs()
          asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one");
 
          asm("addq.w &0x4,%sp");       /* put stack back where it was  */
+#        define HAVE_PUSH_REGS
 #        else /* !__GNUC__ */
          GC_push_one(getreg(REG_A2));
          GC_push_one(getreg(REG_A3));
@@ -174,6 +179,7 @@ void GC_push_regs()
          GC_push_one(getreg(REG_D5));
          GC_push_one(getreg(REG_D6));
          GC_push_one(getreg(REG_D7));
+#        define HAVE_PUSH_REGS
 #       endif /* !__GNUC__ */
 #       endif /* AMIGA */
 
@@ -196,10 +202,12 @@ void GC_push_regs()
               PushMacReg(d7);
               add.w   #4,sp                   ; fix stack.
          }
+#        define HAVE_PUSH_REGS
 #        undef PushMacReg
 #      endif /* THINK_C */
 #      if defined(__MWERKS__)
          PushMacRegisters();
+#        define HAVE_PUSH_REGS
 #      endif   /* __MWERKS__ */
 #   endif      /* MACOS */
 
@@ -222,6 +230,7 @@ void GC_push_regs()
          asm("pushl %esi");  asm("call _GC_push_one"); asm("addl $4,%esp");
          asm("pushl %edi");  asm("call _GC_push_one"); asm("addl $4,%esp");
          asm("pushl %ebx");  asm("call _GC_push_one"); asm("addl $4,%esp");
+#        define HAVE_PUSH_REGS
 #       endif
 
 #      if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \
@@ -244,6 +253,7 @@ void GC_push_regs()
          asm("pushl %esi; call GC_push_one; addl $4,%esp");
          asm("pushl %edi; call GC_push_one; addl $4,%esp");
          asm("pushl %ebx; call GC_push_one; addl $4,%esp");
+#        define HAVE_PUSH_REGS
 #      endif
 
 #      if ( defined(I386) && defined(BEOS) && defined(__ELF__) )
@@ -255,6 +265,7 @@ void GC_push_regs()
          asm("pushl %esi; call GC_push_one; addl $4,%esp");
          asm("pushl %edi; call GC_push_one; addl $4,%esp");
          asm("pushl %ebx; call GC_push_one; addl $4,%esp");
+#        define HAVE_PUSH_REGS
 #       endif
 
 #       if defined(I386) && defined(MSWIN32) && !defined(__MINGW32__) \
@@ -281,6 +292,7 @@ void GC_push_regs()
          __asm  push edi
          __asm  call GC_push_one
          __asm  add esp,4
+#        define HAVE_PUSH_REGS
 #       endif
 
 #       if defined(I386) && (defined(SVR4) || defined(SCO) || defined(SCO_ELF))
@@ -292,6 +304,7 @@ void GC_push_regs()
          asm("pushl %ebp");  asm("call GC_push_one"); asm("addl $4,%esp");
          asm("pushl %esi");  asm("call GC_push_one"); asm("addl $4,%esp");
          asm("pushl %edi");  asm("call GC_push_one"); asm("addl $4,%esp");
+#        define HAVE_PUSH_REGS
 #       endif
 
 #       ifdef NS32K
@@ -300,14 +313,12 @@ void GC_push_regs()
          asm ("movd r5, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
          asm ("movd r6, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
          asm ("movd r7, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
+#        define HAVE_PUSH_REGS
 #       endif
 
 #       if defined(SPARC)
-         {
-             word GC_save_regs_in_stack();
-             
-             GC_save_regs_ret_val = GC_save_regs_in_stack();
-         }
+         GC_save_regs_ret_val = GC_save_regs_in_stack();
+#        define HAVE_PUSH_REGS
 #       endif
 
 #      ifdef RT
@@ -323,6 +334,7 @@ void GC_push_regs()
            asm("cas r11, r13, r0"); GC_push_one(TMP_SP); /* through */
            asm("cas r11, r14, r0"); GC_push_one(TMP_SP); /* r15 */
            asm("cas r11, r15, r0"); GC_push_one(TMP_SP);
+#          define HAVE_PUSH_REGS
 #       endif
 
 #       if defined(M68K) && defined(SYSV)
@@ -346,6 +358,7 @@ void GC_push_regs()
          asm("movl %d7,%sp@"); asm("jbsr GC_push_one");
   
          asm("addqw #0x4,%sp");        /* put stack back where it was  */
+#        define HAVE_PUSH_REGS
 #        else /* !__GNUC__*/
          asm("subq.w &0x4,%sp");       /* allocate word on top of stack */
   
@@ -363,6 +376,7 @@ void GC_push_regs()
          asm("mov.l %d7,(%sp)"); asm("jsr GC_push_one");
   
          asm("addq.w &0x4,%sp");       /* put stack back where it was  */
+#        define HAVE_PUSH_REGS
 #        endif /* !__GNUC__ */
 #       endif /* M68K/SYSV */
 
@@ -372,21 +386,19 @@ void GC_push_regs()
            extern int *__libc_stack_end;
 
            GC_push_all_stack (sp, __libc_stack_end);
+#          define HAVE_PUSH_REGS
+           /* Isn't this redundant with the code to push the stack? */
         }
 #     endif
 
       /* other machines... */
-#       if !defined(M68K) && !defined(VAX) && !defined(RT) 
-#      if !defined(SPARC) && !defined(I386) && !defined(NS32K)
-#      if !defined(POWERPC) && !defined(UTS4) 
-#       if !defined(PJ) && !(defined(MIPS) && defined(LINUX))
-           --> bad news <--
-#      endif
-#       endif
-#       endif
+#       if !defined(HAVE_PUSH_REGS)
+           --> We just generated an empty GC_push_regs, which
+           --> is almost certainly broken.  Try defining
+           --> USE_GENERIC_PUSH_REGS instead.
 #       endif
 }
-#endif /* !USE_GENERIC_PUSH_REGS */
+#endif /* !USE_GENERIC_PUSH_REGS && !USE_ASM_PUSH_REGS */
 
 #if defined(USE_GENERIC_PUSH_REGS)
 void GC_generic_push_regs(cold_gc_frame)
@@ -428,8 +440,6 @@ ptr_t cold_gc_frame;
              /* needed on IA64, since some non-windowed registers are  */
              /* preserved.                                             */
              {
-               word GC_save_regs_in_stack();
-             
                GC_save_regs_ret_val = GC_save_regs_in_stack();
                /* On IA64 gcc, could use __builtin_ia64_flushrs() and  */
                /* __builtin_ia64_flushrs().  The latter will be done   */
@@ -446,7 +456,7 @@ ptr_t cold_gc_frame;
 /* the stack.  Return sp.                                              */
 # ifdef SPARC
     asm("      .seg    \"text\"");
-#   ifdef SVR4
+#   if defined(SVR4) || defined(NETBSD)
       asm("    .globl  GC_save_regs_in_stack");
       asm("GC_save_regs_in_stack:");
       asm("    .type GC_save_regs_in_stack,#function");
diff --git a/mark.c b/mark.c
index 8ca36f13c29c062fd4da274f7c560c4c216cb95a..ca947290291b880de35b19d2ca2a632476fd4322 100644 (file)
--- a/mark.c
+++ b/mark.c
 # include <stdio.h>
 # include "private/gc_pmark.h"
 
+#if defined(MSWIN32) && defined(__GNUC__)
+# include <excpt.h>
+#endif
+
 /* We put this here to minimize the risk of inlining. */
 /*VARARGS*/
 #ifdef __WATCOMC__
@@ -261,20 +265,20 @@ static void alloc_mark_stack();
 /* remains valid until all marking is complete.                */
 /* A zero value indicates that it's OK to miss some    */
 /* register values.                                    */
-GC_bool GC_mark_some(cold_gc_frame)
-ptr_t cold_gc_frame;
+/* We hold the allocation lock.  In the case of        */
+/* incremental collection, the world may not be stopped.*/
+#ifdef MSWIN32
+  /* For win32, this is called after we establish a structured */
+  /* exception handler, in case Windows unmaps one of our root */
+  /* segments.  See below.  In either case, we acquire the     */
+  /* allocator lock long before we get here.                   */
+  GC_bool GC_mark_some_inner(cold_gc_frame)
+  ptr_t cold_gc_frame;
+#else
+  GC_bool GC_mark_some(cold_gc_frame)
+  ptr_t cold_gc_frame;
+#endif
 {
-#if defined(MSWIN32) && !defined(__GNUC__)
-  /* Windows 98 appears to asynchronously create and remove writable   */
-  /* memory mappings, for reasons we haven't yet understood.  Since    */
-  /* we look for writable regions to determine the root set, we may    */
-  /* try to mark from an address range that disappeared since we       */
-  /* started the collection.  Thus we have to recover from faults here. */
-  /* This code does not appear to be necessary for Windows 95/NT/2000. */ 
-  /* Note that this code should never generate an incremental GC write */
-  /* fault.                                                            */
-  __try {
-#endif /* defined(MSWIN32) && !defined(__GNUC__) */
     switch(GC_mark_state) {
        case MS_NONE:
            return(FALSE);
@@ -395,23 +399,130 @@ ptr_t cold_gc_frame;
            ABORT("GC_mark_some: bad state");
            return(FALSE);
     }
-#if defined(MSWIN32) && !defined(__GNUC__)
-  } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
-           EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
-#   ifdef CONDPRINT
-      if (GC_print_stats) {
-       GC_printf0("Caught ACCESS_VIOLATION in marker. "
-                  "Memory mapping disappeared.\n");
+}
+
+
+#ifdef MSWIN32
+
+# ifdef __GNUC__
+
+    typedef struct {
+      EXCEPTION_REGISTRATION ex_reg;
+      void *alt_path;
+    } ext_ex_regn;
+
+
+    static EXCEPTION_DISPOSITION mark_ex_handler(
+        struct _EXCEPTION_RECORD *ex_rec, 
+        void *est_frame,
+        struct _CONTEXT *context,
+        void *disp_ctxt)
+    {
+        if (ex_rec->ExceptionCode == STATUS_ACCESS_VIOLATION) {
+          ext_ex_regn *xer = (ext_ex_regn *)est_frame;
+
+          /* Unwind from the inner function assuming the standard */
+          /* function prologue.                                   */
+          /* Assumes code has not been compiled with              */
+          /* -fomit-frame-pointer.                                */
+          context->Esp = context->Ebp;
+          context->Ebp = *((DWORD *)context->Esp);
+          context->Esp = context->Esp - 8;
+
+          /* Resume execution at the "real" handler within the    */
+          /* wrapper function.                                    */
+          context->Eip = (DWORD )(xer->alt_path);
+
+          return ExceptionContinueExecution;
+
+        } else {
+            return ExceptionContinueSearch;
+        }
+    }
+# endif /* __GNUC__ */
+
+
+  GC_bool GC_mark_some(cold_gc_frame)
+  ptr_t cold_gc_frame;
+  {
+      GC_bool ret_val;
+
+#   ifndef __GNUC__
+      /* Windows 98 appears to asynchronously create and remove  */
+      /* writable memory mappings, for reasons we haven't yet    */
+      /* understood.  Since we look for writable regions to      */
+      /* determine the root set, we may try to mark from an      */
+      /* address range that disappeared since we started the     */
+      /* collection.  Thus we have to recover from faults here.  */
+      /* This code does not appear to be necessary for Windows   */
+      /* 95/NT/2000. Note that this code should never generate   */
+      /* an incremental GC write fault.                          */
+
+      __try {
+
+#   else /* __GNUC__ */
+
+      /* Manually install an exception handler since GCC does    */
+      /* not yet support Structured Exception Handling (SEH) on  */
+      /* Win32.                                                  */
+
+      ext_ex_regn er;
+
+      er.alt_path = &&handle_ex;
+      er.ex_reg.handler = mark_ex_handler;
+      asm volatile ("movl %%fs:0, %0" : "=r" (er.ex_reg.prev));
+      asm volatile ("movl %0, %%fs:0" : : "r" (&er));
+
+#   endif /* __GNUC__ */
+
+          ret_val = GC_mark_some_inner(cold_gc_frame);
+
+#   ifndef __GNUC__
+
+      } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
+                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
+
+#   else /* __GNUC__ */
+
+          /* Prevent GCC from considering the following code unreachable */
+          /* and thus eliminating it.                                    */
+          if (er.alt_path != 0)
+              goto rm_handler;
+
+handle_ex:
+          /* Execution resumes from here on an access violation. */
+
+#   endif /* __GNUC__ */
+
+#         ifdef CONDPRINT
+            if (GC_print_stats) {
+             GC_printf0("Caught ACCESS_VIOLATION in marker. "
+                        "Memory mapping disappeared.\n");
+            }
+#         endif /* CONDPRINT */
+
+          /* We have bad roots on the stack.  Discard mark stack.  */
+          /* Rescan from marked objects.  Redetermine roots.    */
+          GC_invalidate_mark_state();  
+          scan_ptr = 0;
+
+          ret_val = FALSE;
+
+#   ifndef __GNUC__
+
       }
-#   endif /* CONDPRINT */
-    /* We have bad roots on the stack.  Discard mark stack.    */
-    /* Rescan from marked objects.  Redetermine roots.         */
-    GC_invalidate_mark_state();        
-    scan_ptr = 0;
-    return FALSE;
+
+#   else /* __GNUC__ */
+
+rm_handler:
+      /* Uninstall the exception handler */
+      asm volatile ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev));
+
+#   endif /* __GNUC__ */
+
+      return ret_val;
   }
-#endif /* defined(MSWIN32) && !defined(__GNUC__) */
-}
+#endif /* MSWIN32 */
 
 
 GC_bool GC_mark_stack_empty()
@@ -571,6 +682,7 @@ mse * mark_stack_limit;
           while (descr != 0) {
             if ((signed_word)descr < 0) {
               current = *current_p;
+             FIXUP_POINTER(current);
              if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
                PREFETCH(current);
                 HC_PUSH_CONTENTS((ptr_t)current, mark_stack_top,
@@ -645,6 +757,7 @@ mse * mark_stack_limit;
          PREFETCH((ptr_t)limit - PREF_DIST*CACHE_LINE_SIZE);
          GC_ASSERT(limit >= current_p);
          deferred = *limit;
+         FIXUP_POINTER(deferred);
          limit = (word *)((char *)limit - ALIGNMENT);
          if ((ptr_t)deferred >= least_ha && (ptr_t)deferred <  greatest_ha) {
            PREFETCH(deferred);
@@ -654,6 +767,7 @@ mse * mark_stack_limit;
          /* Unroll once, so we don't do too many of the prefetches     */
          /* based on limit.                                            */
          deferred = *limit;
+         FIXUP_POINTER(deferred);
          limit = (word *)((char *)limit - ALIGNMENT);
          if ((ptr_t)deferred >= least_ha && (ptr_t)deferred <  greatest_ha) {
            PREFETCH(deferred);
@@ -668,6 +782,7 @@ mse * mark_stack_limit;
        /* Since HC_PUSH_CONTENTS expands to a lot of code,     */
        /* we don't.                                            */
         current = *current_p;
+       FIXUP_POINTER(current);
         PREFETCH((ptr_t)current_p + PREF_DIST*CACHE_LINE_SIZE);
         if ((ptr_t)current >= least_ha && (ptr_t)current <  greatest_ha) {
          /* Prefetch the contents of the object we just pushed.  It's  */
@@ -1346,8 +1461,8 @@ ptr_t top;
 #   define GC_least_plausible_heap_addr least_ha
 
     if (top == 0) return;
-    /* check all pointers in range and put in push if they appear */
-    /* to be valid.                                              */
+    /* check all pointers in range and push if they appear     */
+    /* to be valid.                                            */
       lim = t - 1 /* longword */;
       for (p = b; p <= lim; p = (word *)(((char *)p) + ALIGNMENT)) {
        q = *p;
@@ -1370,7 +1485,7 @@ ptr_t bottom;
 ptr_t top;
 ptr_t cold_gc_frame;
 {
-  if (GC_all_interior_pointers) {
+  if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
 #   define EAGER_BYTES 1024
     /* Push the hot end of the stack eagerly, so that register values   */
     /* saved inside GC frames are marked before they disappear.                */
@@ -1379,6 +1494,7 @@ ptr_t cold_gc_frame;
        GC_push_all_stack(bottom, top);
        return;
     }
+    GC_ASSERT(bottom <= cold_gc_frame && cold_gc_frame <= top);
 #   ifdef STACK_GROWS_DOWN
        GC_push_all(cold_gc_frame - sizeof(ptr_t), top);
        GC_push_all_eager(bottom, cold_gc_frame);
@@ -1399,7 +1515,7 @@ void GC_push_all_stack(bottom, top)
 ptr_t bottom;
 ptr_t top;
 {
-  if (GC_all_interior_pointers) {
+  if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
     GC_push_all(bottom, top);
   } else {
     GC_push_all_eager(bottom, top);
index 628cba289acaecf5bc36914c14257c0e7c5e5eb6..55eb5d5433953dd860281be12e0d9c90205f9ec9 100644 (file)
@@ -274,6 +274,28 @@ void GC_clear_roots GC_PROTO((void))
     ENABLE_SIGNALS();
 }
 
+/* Internal use only; lock held.       */
+static void GC_remove_root_at_pos(i) 
+int i;
+{
+    GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
+    GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
+    GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
+    GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
+    n_root_sets--;
+}
+
+#if !defined(MSWIN32) && !defined(MSWINCE)
+static void GC_rebuild_root_index()
+{
+    register int i;
+       
+    for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
+    for (i = 0; i < n_root_sets; i++)
+       add_roots_to_index(GC_static_roots + i);
+}
+#endif
+
 /* Internal use only; lock held.       */
 void GC_remove_tmp_roots()
 {
@@ -281,28 +303,45 @@ void GC_remove_tmp_roots()
     
     for (i = 0; i < n_root_sets; ) {
        if (GC_static_roots[i].r_tmp) {
-           GC_root_size -=
-               (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
-           GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
-           GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
-           GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
-           n_root_sets--;
+            GC_remove_root_at_pos(i);
        } else {
            i++;
-       }
     }
-#   if !defined(MSWIN32) && !defined(MSWINCE)
-    {
-       register int i;
-       
-       for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
-       for (i = 0; i < n_root_sets; i++)
-               add_roots_to_index(GC_static_roots + i);
     }
-#   endif
+    #if !defined(MSWIN32) && !defined(MSWINCE)
+    GC_rebuild_root_index();
+    #endif
+}
+
+#if !defined(MSWIN32) && !defined(MSWINCE)
+void GC_remove_roots(b, e)
+char * b; char * e;
+{
+    DCL_LOCK_STATE;
     
+    DISABLE_SIGNALS();
+    LOCK();
+    GC_remove_roots_inner(b, e);
+    UNLOCK();
+    ENABLE_SIGNALS();
 }
 
+/* Should only be called when the lock is held */
+void GC_remove_roots_inner(b,e)
+char * b; char * e;
+{
+    int i;
+    for (i = 0; i < n_root_sets; ) {
+       if (GC_static_roots[i].r_start >= (ptr_t)b && GC_static_roots[i].r_end <= (ptr_t)e) {
+            GC_remove_root_at_pos(i);
+       } else {
+           i++;
+       }
+    }
+    GC_rebuild_root_index();
+}
+#endif /* !defined(MSWIN32) && !defined(MSWINCE) */
+
 #if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)
 /* Workaround for the OS mapping and unmapping behind our back:                */
 /* Is the address p in one of the temporary static root sections?      */
@@ -506,6 +545,17 @@ void GC_push_gc_structures GC_PROTO((void))
   void GC_mark_thread_local_free_lists();
 #endif
 
+void GC_cond_register_dynamic_libraries()
+{
+# if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
+     || defined(PCR)) && !defined(SRC_M3)
+    GC_remove_tmp_roots();
+    if (!GC_no_dls) GC_register_dynamic_libraries();
+# else
+    GC_no_dls = TRUE;
+# endif
+}
+
 /*
  * Call the mark routines (GC_tl_push for a single pointer, GC_push_conditional
  * on groups of pointers) on every top level accessible pointer.
@@ -519,19 +569,20 @@ void GC_push_roots(all, cold_gc_frame)
 GC_bool all;
 ptr_t cold_gc_frame;
 {
-    register int i;
+    int i;
+    int kind;
 
     /*
      * Next push static data.  This must happen early on, since it's
      * not robust against mark stack overflow.
      */
-     /* Reregister dynamic libraries, in case one got added.   */
-#      if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
-          || defined(PCR)) && !defined(SRC_M3)
-         GC_remove_tmp_roots();
-         if (!GC_no_dls) GC_register_dynamic_libraries();
-#      else
-        GC_no_dls = TRUE;
+     /* Reregister dynamic libraries, in case one got added.           */
+     /* There is some argument for doing this as late as possible,     */
+     /* especially on win32, where it can change asynchronously.       */
+     /* In those cases, we do it here.  But on other platforms, it's   */
+     /* not safe with the world stopped, so we do it earlier.          */
+#      if !defined(REGISTER_LIBRARIES_EARLY)
+         GC_cond_register_dynamic_libraries();
 #      endif
 
      /* Mark everything in static data areas                             */
@@ -541,6 +592,18 @@ ptr_t cold_gc_frame;
                             GC_static_roots[i].r_end, all);
        }
 
+     /* Mark all free list header blocks, if those were allocated from */
+     /* the garbage collected heap.  This makes sure they don't        */
+     /* disappear if we are not marking from static data.  It also     */
+     /* saves us the trouble of scanning them, and possibly that of    */
+     /* marking the freelists.                                         */
+       for (kind = 0; kind < GC_n_kinds; kind++) {
+        GC_PTR base = GC_base(GC_obj_kinds[kind].ok_freelist);
+        if (0 != base) {
+          GC_set_mark_bit(base);
+        }
+       }
+       
      /* Mark from GC internal roots if those might otherwise have      */
      /* been excluded.                                                 */
        if (GC_no_dls || roots_were_cleared) {
@@ -549,8 +612,11 @@ ptr_t cold_gc_frame;
 
      /* Mark thread local free lists, even if their mark       */
      /* descriptor excludes the link field.                    */
+     /* If the world is not stopped, this is unsafe.  It is    */
+     /* also unnecessary, since we will do this again with the */
+     /* world stopped.                                         */
 #      ifdef THREAD_LOCAL_ALLOC
-         GC_mark_thread_local_free_lists();
+         if (GC_world_stopped) GC_mark_thread_local_free_lists();
 #      endif
 
     /*
similarity index 74%
rename from mips_sgi_mach_dep.S
rename to mips_sgi_mach_dep.s
index bae9b5ebfe4117be1c262d8239eb14cbce5eb2ad..56390280a718845293455066595083420c477f8f 100644 (file)
@@ -1,5 +1,10 @@
 #include <sys/regdef.h>
 #include <sys/asm.h>
+/* This file must be preprocessed.  But the SGI assembler always does  */
+/* that.  Furthermore, a generic preprocessor won't do, since some of  */
+/* the SGI-supplied include files rely on behavior of the MIPS                 */
+/* assembler.  Hence we treat and name this file as though it required */
+/* no preprocessing.                                                   */
 
 # define call_push(x)     move    $4,x;    jal     GC_push_one
 
diff --git a/misc.c b/misc.c
index 2d6421eea9e0ac39582998c38b37d955cf4b50f0..814fa41ab2497189bc801856831b73833eae2313 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -49,7 +49,7 @@
 #          if defined(GC_WIN32_THREADS) 
 #             if defined(GC_PTHREADS)
                  pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER;
-#            elif !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL))
+#            elif defined(GC_DLL)
                 __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml;
 #            else
                 CRITICAL_SECTION GC_allocate_ml;
 #undef STACKBASE
 #endif
 
+/* Dont unnecessarily call GC_register_main_static_data() in case      */
+/* dyn_load.c isn't linked in.                                         */
+#ifdef DYNAMIC_LOADING
+# define GC_REGISTER_MAIN_STATIC_DATA() GC_register_main_static_data()
+#else
+# define GC_REGISTER_MAIN_STATIC_DATA() TRUE
+#endif
+
 GC_FAR struct _GC_arrays GC_arrays /* = { 0 } */;
 
 
@@ -136,6 +144,13 @@ GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requested)) = GC_default_oom_fn;
 
 extern signed_word GC_mem_found;
 
+void * GC_project2(arg1, arg2)
+void *arg1;
+void *arg2;
+{
+  return arg2;
+}
+
 # ifdef MERGE_SIZES
     /* Set things up so that GC_size_map[i] >= words(i),               */
     /* but not too much bigger                                         */
@@ -472,6 +487,15 @@ void GC_init()
          GC_init_parallel();
        }
 #   endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
+
+#   if defined(DYNAMIC_LOADING) && defined(DARWIN)
+    {
+        /* This must be called WITHOUT the allocation lock held
+        and before any threads are created */
+        extern void GC_init_dyld();
+        GC_init_dyld();
+    }
+#   endif
 }
 
 #if defined(MSWIN32) || defined(MSWINCE)
@@ -484,6 +508,22 @@ void GC_init()
 
 extern void GC_setpagesize();
 
+
+#ifdef MSWIN32
+extern GC_bool GC_no_win32_dlls;
+#else
+# define GC_no_win32_dlls FALSE
+#endif
+
+void GC_exit_check GC_PROTO((void))
+{
+   GC_gcollect();
+}
+
+#ifdef SEARCH_FOR_DATA_START
+  extern void GC_init_linux_data_start GC_PROTO((void));
+#endif
+
 #ifdef UNIX_LIKE
 
 extern void GC_set_and_save_fault_handler GC_PROTO((void (*handler)(int)));
@@ -494,19 +534,25 @@ int sig;
     GC_err_printf1("Caught signal %d: looping in handler\n", sig);
     for(;;);
 }
-#endif
 
-#ifdef MSWIN32
-extern GC_bool GC_no_win32_dlls;
-#else
-# define GC_no_win32_dlls FALSE
-#endif
+static GC_bool installed_looping_handler = FALSE;
 
-void GC_exit_check GC_PROTO((void))
+void maybe_install_looping_handler()
 {
-   GC_gcollect();
+    /* Install looping handler before the write fault handler, so we   */
+    /* handle write faults correctly.                                  */
+      if (!installed_looping_handler && 0 != GETENV("GC_LOOP_ON_ABORT")) {
+        GC_set_and_save_fault_handler(looping_handler);
+        installed_looping_handler = TRUE;
+      }
 }
 
+#else /* !UNIX_LIKE */
+
+# define maybe_install_looping_handler()
+
+#endif
+
 void GC_init_inner()
 {
 #   if !defined(THREADS) && defined(GC_ASSERTIONS)
@@ -524,9 +570,11 @@ void GC_init_inner()
     if (0 != GETENV("GC_PRINT_STATS")) {
       GC_print_stats = 1;
     } 
-    if (0 != GETENV("GC_DUMP_REGULARLY")) {
-      GC_dump_regularly = 1;
-    }
+#   ifndef NO_DEBUGGING
+      if (0 != GETENV("GC_DUMP_REGULARLY")) {
+        GC_dump_regularly = 1;
+      }
+#   endif
     if (0 != GETENV("GC_FIND_LEAK")) {
       GC_find_leak = 1;
 #     ifdef __STDC__
@@ -569,11 +617,7 @@ void GC_init_inner()
         }
       }
     }
-#   ifdef UNIX_LIKE
-      if (0 != GETENV("GC_LOOP_ON_ABORT")) {
-        GC_set_and_save_fault_handler(looping_handler);
-      }
-#   endif
+    maybe_install_looping_handler();
     /* Adjust normal object descriptor for extra allocation.   */
     if (ALIGNMENT > GC_DS_TAGS && EXTRA_BYTES != 0) {
       GC_obj_kinds[NORMAL].ok_descriptor = ((word)(-ALIGNMENT) | GC_DS_LENGTH);
@@ -608,11 +652,21 @@ void GC_init_inner()
 #       if defined(LINUX) && defined(IA64)
          GC_register_stackbottom = GC_get_register_stack_base();
 #       endif
+      } else {
+#       if defined(LINUX) && defined(IA64)
+         if (GC_register_stackbottom == 0) {
+           WARN("GC_register_stackbottom should be set with GC_stackbottom", 0);
+           /* The following is likely to fail, since we rely on        */
+           /* alignment properties that may not hold with a user set   */
+           /* GC_stackbottom.                                          */
+           GC_register_stackbottom = GC_get_register_stack_base();
+         }
+#      endif
       }
 #   endif
-    GC_ASSERT(sizeof (ptr_t) == sizeof(word));
-    GC_ASSERT(sizeof (signed_word) == sizeof(word));
-    GC_ASSERT(sizeof (struct hblk) == HBLKSIZE);
+    GC_STATIC_ASSERT(sizeof (ptr_t) == sizeof(word));
+    GC_STATIC_ASSERT(sizeof (signed_word) == sizeof(word));
+    GC_STATIC_ASSERT(sizeof (struct hblk) == HBLKSIZE);
 #   ifndef THREADS
 #     if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
        ABORT(
@@ -636,7 +690,7 @@ void GC_init_inner()
     
     /* Add initial guess of root sets.  Do this first, since sbrk(0)   */
     /* might be used.                                                  */
-      GC_register_data_segments();
+      if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments();
     GC_init_headers();
     GC_bl_init();
     GC_mark_init();
@@ -734,8 +788,9 @@ void GC_enable_incremental GC_PROTO(())
     if (GC_incremental) goto out;
     GC_setpagesize();
     if (GC_no_win32_dlls) goto out;
-#   ifndef GC_SOLARIS_THREADS
-        GC_dirty_init();
+#   ifndef GC_SOLARIS_THREADS 
+      maybe_install_looping_handler();  /* Before write fault handler! */
+      GC_dirty_init();
 #   endif
     if (!GC_is_initialized) {
         GC_init_inner();
@@ -954,6 +1009,17 @@ GC_warn_proc GC_current_warn_proc = GC_default_warn_proc;
     return(result);
 }
 
+# if defined(__STDC__) || defined(__cplusplus)
+    GC_word GC_set_free_space_divisor (GC_word value)
+# else
+    GC_word GC_set_free_space_divisor (value)
+    GC_word value;
+# endif
+{
+    GC_word old = GC_free_space_divisor;
+    GC_free_space_divisor = value;
+    return old;
+}
 
 #ifndef PCR
 void GC_abort(msg)
@@ -980,17 +1046,18 @@ GC_CONST char * msg;
 }
 #endif
 
-
-/* Needed by SRC_M3, gcj, and should perhaps be the official interface */
-/* to GC_dont_gc.                                                      */
 void GC_enable()
 {
+    LOCK();
     GC_dont_gc--;
+    UNLOCK();
 }
 
 void GC_disable()
 {
+    LOCK();
     GC_dont_gc++;
+    UNLOCK();
 }
 
 #if !defined(NO_DEBUGGING)
index 5e8115459678cd7558431b3633c9f8da3b374bb5..cb8d0b6b7bb53ebb8d47bddf0c2f19144001d90c 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
 #   define NEED_FIND_LIMIT
 # endif
 
-#ifdef NEED_FIND_LIMIT
-#   include <setjmp.h>
-#endif
-
 #if defined(FREEBSD) && defined(I386)
 #  include <machine/trap.h>
+#  if !defined(PCR)
+#    define NEED_FIND_LIMIT
+#  endif
+#endif
+
+#ifdef NEED_FIND_LIMIT
+#   include <setjmp.h>
 #endif
 
 #ifdef AMIGA
 # define jmp_buf sigjmp_buf
 #endif
 
+#ifdef DARWIN
+/* for get_etext and friends */
+#include <mach-o/getsect.h>
+#endif
+
 #ifdef DJGPP
   /* Apparently necessary for djgpp 2.01.  May cause problems with     */
   /* other versions.                                                   */
 # define OPT_PROT_EXEC 0
 #endif
 
+#if defined(LINUX) && \
+    (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64) || !defined(SMALL_CONFIG))
+
+/* We need to parse /proc/self/maps, either to find dynamic libraries, */
+/* and/or to find the register backing store base (IA64).  Do it once  */
+/* here.                                                               */
+
+#define READ read
+
+/* Repeatedly perform a read call until the buffer is filled or        */
+/* we encounter EOF.                                           */
+ssize_t GC_repeat_read(int fd, char *buf, size_t count)
+{
+    ssize_t num_read = 0;
+    ssize_t result;
+    
+    while (num_read < count) {
+       result = READ(fd, buf + num_read, count - num_read);
+       if (result < 0) return result;
+       if (result == 0) break;
+       num_read += result;
+    }
+    return num_read;
+}
+
+/*
+ * Apply fn to a buffer containing the contents of /proc/self/maps.
+ * Return the result of fn or, if we failed, 0.
+ */
+
+word GC_apply_to_maps(word (*fn)(char *))
+{
+    int f;
+    int result;
+    int maps_size;
+    char maps_temp[32768];
+    char *maps_buf;
+
+    /* Read /proc/self/maps    */
+        /* Note that we may not allocate, and thus can't use stdio.    */
+        f = open("/proc/self/maps", O_RDONLY);
+        if (-1 == f) return 0;
+       /* stat() doesn't work for /proc/self/maps, so we have to
+          read it to find out how large it is... */
+       maps_size = 0;
+       do {
+           result = GC_repeat_read(f, maps_temp, sizeof(maps_temp));
+           if (result <= 0) return 0;
+           maps_size += result;
+       } while (result == sizeof(maps_temp));
+
+       if (maps_size > sizeof(maps_temp)) {
+           /* If larger than our buffer, close and re-read it. */
+           close(f);
+           f = open("/proc/self/maps", O_RDONLY);
+           if (-1 == f) return 0;
+           maps_buf = alloca(maps_size);
+           if (NULL == maps_buf) return 0;
+           result = GC_repeat_read(f, maps_buf, maps_size);
+           if (result <= 0) return 0;
+       } else {
+           /* Otherwise use the fixed size buffer */
+           maps_buf = maps_temp;
+       }
+
+       close(f);
+        maps_buf[result] = '\0';
+       
+    /* Apply fn to result. */
+       return fn(maps_buf);
+}
+
+#endif /* Need GC_apply_to_maps */
+
+#if defined(LINUX) && (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64))
+//
+//  GC_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
+//  
+//  For 64 bit ABIs:
+//  0       17       34            56
+//
+//  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'.)
+//
+#if CPP_WORDSZ == 32
+# define OFFSET_MAP_START   0
+# define OFFSET_MAP_END     9
+# define OFFSET_MAP_PROT   18
+# define OFFSET_MAP_MAJDEV 32
+# define ADDR_WIDTH        8
+#endif
+
+#if CPP_WORDSZ == 64
+# define OFFSET_MAP_START   0
+# define OFFSET_MAP_END    17
+# define OFFSET_MAP_PROT   34
+# define OFFSET_MAP_MAJDEV 56
+# define ADDR_WIDTH       16
+#endif
+
+/*
+ * Assign various fields of the first line in buf_ptr to *start, *end,
+ * *prot_buf and *maj_dev.  Only *prot_buf may be set for unwritable maps.
+ */
+char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,
+                                char *prot_buf, unsigned int *maj_dev)
+{
+    int i;
+    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+ADDR_WIDTH] = '\0';
+        *start = strtoul(tok, NULL, 16);
+
+        tok = buf_ptr+OFFSET_MAP_END;
+        buf_ptr[OFFSET_MAP_END+ADDR_WIDTH] = '\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 /* Need to parse /proc/self/maps. */    
+
 #if defined(SEARCH_FOR_DATA_START)
   /* The I386 case can be handled without a search.  The Alpha case    */
   /* used to be handled differently as well, but the rules changed     */
@@ -622,7 +780,8 @@ ptr_t GC_get_stack_base()
     }
 
     /* Return the first nonaddressible location > p (up) or    */
-    /* the smallest location q s.t. [q,p] is addressible (!up).        */
+    /* the smallest location q s.t. [q,p) is addressable (!up).        */
+    /* We assume that p (up) or p-1 (!up) is addressable.      */
     ptr_t GC_find_limit(p, up)
     ptr_t p;
     GC_bool up;
@@ -666,6 +825,7 @@ ptr_t GC_get_stack_base()
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <ctype.h>
 
 # define STAT_SKIP 27   /* Number of fields preceding startstack       */
                        /* field in /proc/self/stat                     */
@@ -674,6 +834,33 @@ ptr_t GC_get_stack_base()
   extern ptr_t __libc_stack_end;
 
 # ifdef IA64
+    /* Try to read the backing store base from /proc/self/maps.        */
+    /* We look for the writable mapping with a 0 major device,  */
+    /* which is        as close to our frame as possible, but below it.*/
+    static word backing_store_base_from_maps(char *maps)
+    {
+      char prot_buf[5];
+      char *buf_ptr = maps;
+      word start, end;
+      unsigned int maj_dev;
+      word current_best = 0;
+      word dummy;
+  
+      for (;;) {
+        buf_ptr = GC_parse_map_entry(buf_ptr, &start, &end, prot_buf, &maj_dev);
+       if (buf_ptr == NULL) return current_best;
+       if (prot_buf[1] == 'w' && maj_dev == 0) {
+           if (end < (word)(&dummy) && start > current_best) current_best = start;
+       }
+      }
+      return current_best;
+    }
+
+    static word backing_store_base_from_proc(void)
+    {
+        return GC_apply_to_maps(backing_store_base_from_maps);
+    }
+
 #   pragma weak __libc_ia64_register_backing_store_base
     extern ptr_t __libc_ia64_register_backing_store_base;
 
@@ -683,13 +870,19 @@ ptr_t GC_get_stack_base()
          && 0 != __libc_ia64_register_backing_store_base) {
        /* Glibc 2.2.4 has a bug such that for dynamically linked       */
        /* executables __libc_ia64_register_backing_store_base is       */
-       /* defined but ininitialized during constructor calls.          */
+       /* defined but uninitialized during constructor calls.          */
        /* Hence we check for both nonzero address and value.           */
        return __libc_ia64_register_backing_store_base;
       } else {
-       word result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT;
-       result += BACKING_STORE_ALIGNMENT - 1;
-       result &= ~(BACKING_STORE_ALIGNMENT - 1);
+       word result = backing_store_base_from_proc();
+       if (0 == result) {
+         /* Use dumb heuristics.  Works only for default configuration. */
+         result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT;
+         result += BACKING_STORE_ALIGNMENT - 1;
+         result &= ~(BACKING_STORE_ALIGNMENT - 1);
+         /* Verify that it's at least readable.  If not, we goofed. */
+         GC_noop1(*(word *)result); 
+       }
        return (ptr_t)result;
       }
     }
@@ -701,11 +894,8 @@ ptr_t GC_get_stack_base()
     /* using direct I/O system calls in order to avoid calling malloc   */
     /* in case REDIRECT_MALLOC is defined.                             */ 
 #   define STAT_BUF_SIZE 4096
-#   if defined(GC_USE_LD_WRAP)
-#      define STAT_READ __real_read
-#   else
-#      define STAT_READ read
-#   endif    
+#   define STAT_READ read
+         /* Should probably call the real read, if read is wrapped.    */
     char stat_buf[STAT_BUF_SIZE];
     int f;
     char c;
@@ -777,8 +967,11 @@ ptr_t GC_get_stack_base()
 
 ptr_t GC_get_stack_base()
 {
+#   if defined(HEURISTIC1) || defined(HEURISTIC2) || \
+       defined(LINUX_STACKBOTTOM) || defined(FREEBSD_STACKBOTTOM)
     word dummy;
     ptr_t result;
+#   endif
 
 #   define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1)
 
@@ -939,12 +1132,11 @@ void GC_register_data_segments()
   /* invalid result.  Under NT, GC_register_data_segments is a noop and        */
   /* all real work is done by GC_register_dynamic_libraries.  Under    */
   /* win32s, we cannot find the data segments associated with dll's.   */
-  /* We rgister the main data segment here.                            */
-#  ifdef __GCC__
-  GC_bool GC_no_win32_dlls = TRUE;      /* GCC can't do SEH, so we can't use VirtualQuery */
-#  else
+  /* We register the main data segment here.                           */
   GC_bool GC_no_win32_dlls = FALSE;     
-#  endif
+       /* This used to be set for gcc, to avoid dealing with           */
+       /* the structured exception handling issues.  But we now have   */
+       /* assembly code to do that right.                              */
   
   void GC_init_win32()
   {
@@ -976,36 +1168,102 @@ void GC_register_data_segments()
     return(p);
   }
 # endif
+
+# ifndef REDIRECT_MALLOC
+  /* We maintain a linked list of AllocationBase values that we know   */
+  /* correspond to malloc heap sections.  Currently this is only called */
+  /* during a GC.  But there is some hope that for long running                */
+  /* programs we will eventually see most heap sections.               */
+
+  /* In the long run, it would be more reliable to occasionally walk   */
+  /* the malloc heap with HeapWalk on the default heap.  But that      */
+  /* apparently works only for NT-based Windows.                       */ 
+
+  /* In the long run, a better data structure would also be nice ...   */
+  struct GC_malloc_heap_list {
+    void * allocation_base;
+    struct GC_malloc_heap_list *next;
+  } *GC_malloc_heap_l = 0;
+
+  /* Is p the base of one of the malloc heap sections we already know  */
+  /* about?                                                            */
+  GC_bool GC_is_malloc_heap_base(ptr_t p)
+  {
+    struct GC_malloc_heap_list *q = GC_malloc_heap_l;
+
+    while (0 != q) {
+      if (q -> allocation_base == p) return TRUE;
+      q = q -> next;
+    }
+    return FALSE;
+  }
+
+  void *GC_get_allocation_base(void *p)
+  {
+    MEMORY_BASIC_INFORMATION buf;
+    DWORD result = VirtualQuery(p, &buf, sizeof(buf));
+    if (result != sizeof(buf)) {
+      ABORT("Weird VirtualQuery result");
+    }
+    return buf.AllocationBase;
+  }
+
+  size_t GC_max_root_size = 100000;    /* Appr. largest root size.     */
+
+  void GC_add_current_malloc_heap()
+  {
+    struct GC_malloc_heap_list *new_l =
+                 malloc(sizeof(struct GC_malloc_heap_list));
+    void * candidate = GC_get_allocation_base(new_l);
+
+    if (new_l == 0) return;
+    if (GC_is_malloc_heap_base(candidate)) {
+      /* Try a little harder to find malloc heap.                      */
+       size_t req_size = 10000;
+       do {
+         void *p = malloc(req_size);
+         if (0 == p) { free(new_l); return; }
+         candidate = GC_get_allocation_base(p);
+         free(p);
+         req_size *= 2;
+       } while (GC_is_malloc_heap_base(candidate)
+                && req_size < GC_max_root_size/10 && req_size < 500000);
+       if (GC_is_malloc_heap_base(candidate)) {
+         free(new_l); return;
+       }
+    }
+#   ifdef CONDPRINT
+      if (GC_print_stats)
+         GC_printf1("Found new system malloc AllocationBase at 0x%lx\n",
+                     candidate);
+#   endif
+    new_l -> allocation_base = candidate;
+    new_l -> next = GC_malloc_heap_l;
+    GC_malloc_heap_l = new_l;
+  }
+# endif /* REDIRECT_MALLOC */
   
   /* Is p the start of either the malloc heap, or of one of our */
   /* heap sections?                                            */
   GC_bool GC_is_heap_base (ptr_t p)
   {
      
-     register unsigned i;
+     unsigned i;
      
 #    ifndef REDIRECT_MALLOC
-       static ptr_t malloc_heap_pointer = 0;
+       static word last_gc_no = -1;
      
-       if (0 == malloc_heap_pointer) {
-         MEMORY_BASIC_INFORMATION buf;
-         void *pTemp = malloc( 1 );
-         register DWORD result = VirtualQuery(pTemp, &buf, sizeof(buf));
-           
-         free( pTemp );
-
-         
-         if (result != sizeof(buf)) {
-             ABORT("Weird VirtualQuery result");
-         }
-         malloc_heap_pointer = (ptr_t)(buf.AllocationBase);
+       if (last_gc_no != GC_gc_no) {
+        GC_add_current_malloc_heap();
+        last_gc_no = GC_gc_no;
        }
-       if (p == malloc_heap_pointer) return(TRUE);
+       if (GC_root_size > GC_max_root_size) GC_max_root_size = GC_root_size;
+       if (GC_is_malloc_heap_base(p)) return TRUE;
 #    endif
      for (i = 0; i < GC_n_heap_bases; i++) {
-         if (GC_heap_bases[i] == p) return(TRUE);
+         if (GC_heap_bases[i] == p) return TRUE;
      }
-     return(FALSE);
+     return FALSE ;
   }
 
 # ifdef MSWIN32
@@ -1055,7 +1313,7 @@ void GC_register_data_segments()
 
 # if (defined(SVR4) || defined(AUX) || defined(DGUX) \
       || (defined(LINUX) && defined(SPARC))) && !defined(PCR)
-char * GC_SysVGetDataStart(max_page_size, etext_addr)
+ptr_t GC_SysVGetDataStart(max_page_size, etext_addr)
 int max_page_size;
 int * etext_addr;
 {
@@ -1081,10 +1339,43 @@ int * etext_addr;
        /* string constants in the text segment, but after etext.       */
        /* Use plan B.  Note that we now know there is a gap between    */
        /* text and data segments, so plan A bought us something.       */
-       result = (char *)GC_find_limit((ptr_t)(DATAEND) - MIN_PAGE_SIZE, FALSE);
+       result = (char *)GC_find_limit((ptr_t)(DATAEND), FALSE);
+    }
+    return((ptr_t)result);
+}
+# endif
+
+# if defined(FREEBSD) && defined(I386) && !defined(PCR)
+/* Its unclear whether this should be identical to the above, or       */
+/* whether it should apply to non-X86 architectures.                   */
+/* For now we don't assume that there is always an empty page after    */
+/* etext.  But in some cases there actually seems to be slightly more.  */
+/* This also deals with holes between read-only data and writable data.        */
+ptr_t GC_FreeBSDGetDataStart(max_page_size, etext_addr)
+int max_page_size;
+int * etext_addr;
+{
+    word text_end = ((word)(etext_addr) + sizeof(word) - 1)
+                    & ~(sizeof(word) - 1);
+       /* etext rounded to word boundary       */
+    VOLATILE word next_page = (text_end + (word)max_page_size - 1)
+                             & ~((word)max_page_size - 1);
+    VOLATILE ptr_t result = (ptr_t)text_end;
+    GC_setup_temporary_fault_handler();
+    if (setjmp(GC_jmp_buf) == 0) {
+       /* Try reading at the address.                          */
+       /* This should happen before there is another thread.   */
+       for (; next_page < (word)(DATAEND); next_page += (word)max_page_size)
+           *(VOLATILE char *)next_page;
+       GC_reset_fault_handler();
+    } else {
+       GC_reset_fault_handler();
+       /* As above, we go to plan B    */
+       result = GC_find_limit((ptr_t)(DATAEND), FALSE);
     }
-    return((char *)result);
+    return(result);
 }
+
 # endif
 
 
@@ -1098,8 +1389,7 @@ int * etext_addr;
 
 void GC_register_data_segments()
 {
-#   if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \
-       && !defined(MACOSX)
+#   if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS)
 #     if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
        /* As of Solaris 2.3, the Solaris threads implementation        */
        /* allocates the data structure for the initial thread with     */
@@ -1116,9 +1406,6 @@ void GC_register_data_segments()
 #       endif
 #     endif
 #   endif
-#   if !defined(PCR) && (defined(NEXT) || defined(MACOSX))
-      GC_add_roots_inner(DATASTART, (char *) get_end(), FALSE);
-#   endif
 #   if defined(MACOS)
     {
 #   if defined(THINK_C)
@@ -1228,18 +1515,28 @@ word bytes;
 ptr_t GC_unix_get_mem(bytes)
 word bytes;
 {
-    static GC_bool initialized = FALSE;
-    static int fd;
     void *result;
     static ptr_t last_addr = HEAP_START;
 
-    if (!initialized) {
-       fd = open("/dev/zero", O_RDONLY);
-       initialized = TRUE;
-    }
+#   ifndef USE_MMAP_ANON
+      static GC_bool initialized = FALSE;
+      static int fd;
+
+      if (!initialized) {
+         fd = open("/dev/zero", O_RDONLY);
+         fcntl(fd, F_SETFD, FD_CLOEXEC);
+         initialized = TRUE;
+      }
+#   endif
+
     if (bytes & (GC_page_size -1)) ABORT("Bad GET_MEM arg");
-    result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
-                 GC_MMAP_FLAGS, fd, 0/* offset */);
+#   ifdef USE_MMAP_ANON
+      result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
+                   GC_MMAP_FLAGS | MAP_ANON, -1, 0/* offset */);
+#   else
+      result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
+                   GC_MMAP_FLAGS, fd, 0/* offset */);
+#   endif
     if (result == MAP_FAILED) return(0);
     last_addr = (ptr_t)result + bytes + GC_page_size - 1;
     last_addr = (ptr_t)((word)last_addr & ~(GC_page_size - 1));
@@ -1532,6 +1829,7 @@ void GC_remap(ptr_t start, word bytes)
       }
 #   else
       if (-1 == zero_descr) zero_descr = open("/dev/zero", O_RDWR);
+      fcntl(zero_descr, F_SETFD, FD_CLOEXEC);
       if (0 == start_addr) return;
       result = mmap(start_addr, len, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
                    MAP_FIXED | MAP_PRIVATE, zero_descr, 0);
@@ -1718,7 +2016,6 @@ void (*GC_push_other_roots) GC_PROTO((void)) = GC_default_push_other_roots;
  *             make sure that other system calls are similarly protected
  *             or write only to the stack.
  */
 GC_bool GC_dirty_maintained = FALSE;
 
 # ifdef DEFAULT_VDB
@@ -1732,6 +2029,9 @@ GC_bool GC_dirty_maintained = FALSE;
 /* Initialize virtual dirty bit implementation.                        */
 void GC_dirty_init()
 {
+#   ifdef PRINTSTATS
+      GC_printf0("Initializing DEFAULT_VDB...\n");
+#   endif
     GC_dirty_maintained = TRUE;
 }
 
@@ -1814,7 +2114,7 @@ GC_bool is_ptrfree;
  * objects only if they are the same.
  */
 
-# if !defined(MSWIN32) && !defined(MSWINCE)
+# if !defined(MSWIN32) && !defined(MSWINCE) && !defined(DARWIN)
 
 #   include <sys/mman.h>
 #   include <signal.h>
@@ -1833,6 +2133,23 @@ GC_bool is_ptrfree;
          
 # else
 
+# ifdef DARWIN
+    /* Using vm_protect (mach syscall) over mprotect (BSD syscall) seems to
+       decrease the likelihood of some of the problems described below. */
+    #include <mach/vm_map.h>
+    extern mach_port_t GC_task_self;
+    #define PROTECT(addr,len) \
+        if(vm_protect(GC_task_self,(vm_address_t)(addr),(vm_size_t)(len), \
+                FALSE,VM_PROT_READ) != KERN_SUCCESS) { \
+            ABORT("vm_portect failed"); \
+        }
+    #define UNPROTECT(addr,len) \
+        if(vm_protect(GC_task_self,(vm_address_t)(addr),(vm_size_t)(len), \
+                FALSE,VM_PROT_READ|VM_PROT_WRITE) != KERN_SUCCESS) { \
+            ABORT("vm_portect failed"); \
+        }
+# else
+    
 #   ifndef MSWINCE
 #     include <signal.h>
 #   endif
@@ -1850,20 +2167,22 @@ GC_bool is_ptrfree;
                              &protect_junk)) { \
            ABORT("un-VirtualProtect failed"); \
          }
-         
-# endif
+# endif /* !DARWIN */
+# endif /* MSWIN32 || MSWINCE || DARWIN */
 
 #if defined(SUNOS4) || defined(FREEBSD)
     typedef void (* SIG_PF)();
-#endif
+#endif /* SUNOS4 || FREEBSD */
+
 #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
-    || defined(MACOSX) || defined(HURD)
+    || defined(HURD)
 # ifdef __STDC__
     typedef void (* SIG_PF)(int);
 # else
     typedef void (* SIG_PF)();
 # endif
-#endif
+#endif /* SUNOS5SIGS || OSF1 || LINUX || HURD */
+
 #if defined(MSWIN32)
     typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_PF;
 #   undef SIG_DFL
@@ -1877,7 +2196,8 @@ GC_bool is_ptrfree;
 
 #if defined(IRIX5) || defined(OSF1) || defined(HURD)
     typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
-#endif
+#endif /* IRIX5 || OSF1 || HURD */
+
 #if defined(SUNOS5SIGS)
 # ifdef HPUX
 #   define SIGINFO __siginfo
@@ -1889,7 +2209,8 @@ GC_bool is_ptrfree;
 # else
     typedef void (* REAL_SIG_PF)();
 # endif
-#endif
+#endif /* SUNOS5SIGS */
+
 #if defined(LINUX)
 #   if __GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2
       typedef struct sigcontext s_c;
@@ -1923,139 +2244,14 @@ GC_bool is_ptrfree;
        return (char *)faultaddr;
     }
 #   endif /* !ALPHA */
-# endif
-
-# if defined(MACOSX) /* Should also test for PowerPC? */
-    typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
-
-/* Decodes the machine instruction which was responsible for the sending of the
-   SIGBUS signal. Sadly this is the only way to find the faulting address because
-   the signal handler doesn't get it directly from the kernel (although it is
-   available on the Mach level, but droppped by the BSD personality before it
-   calls our signal handler...)
-   This code should be able to deal correctly with all PPCs starting from the
-   601 up to and including the G4s (including Velocity Engine). */
-#define EXTRACT_OP1(iw)     (((iw) & 0xFC000000) >> 26)
-#define EXTRACT_OP2(iw)     (((iw) & 0x000007FE) >> 1)
-#define EXTRACT_REGA(iw)    (((iw) & 0x001F0000) >> 16)
-#define EXTRACT_REGB(iw)    (((iw) & 0x03E00000) >> 21)
-#define EXTRACT_REGC(iw)    (((iw) & 0x0000F800) >> 11)
-#define EXTRACT_DISP(iw)    ((short *) &(iw))[1]
-
-static char *get_fault_addr(struct sigcontext *scp)
-{
-   unsigned int   instr = *((unsigned int *) scp->sc_ir);
-   unsigned int * regs = &((unsigned int *) scp->sc_regs)[2];
-   int            disp = 0, tmp;
-   unsigned int   baseA = 0, baseB = 0;
-   unsigned int   addr, alignmask = 0xFFFFFFFF;
-
-#ifdef GC_DEBUG_DECODER
-   GC_err_printf1("Instruction: 0x%lx\n", instr);
-   GC_err_printf1("Opcode 1: d\n", (int)EXTRACT_OP1(instr));
-#endif
-   switch(EXTRACT_OP1(instr)) {
-      case 38:   /* stb */
-      case 39:   /* stbu */
-      case 54:   /* stfd */
-      case 55:   /* stfdu */
-      case 52:   /* stfs */
-      case 53:   /* stfsu */
-      case 44:   /* sth */
-      case 45:   /* sthu */
-      case 47:   /* stmw */
-      case 36:   /* stw */
-      case 37:   /* stwu */
-            tmp = EXTRACT_REGA(instr);
-            if(tmp > 0)
-               baseA = regs[tmp];
-            disp = EXTRACT_DISP(instr);
-            break;
-      case 31:
-#ifdef GC_DEBUG_DECODER
-            GC_err_printf1("Opcode 2: %d\n", (int)EXTRACT_OP2(instr));
-#endif
-            switch(EXTRACT_OP2(instr)) {
-               case 86:    /* dcbf */
-               case 54:    /* dcbst */
-               case 1014:  /* dcbz */
-               case 247:   /* stbux */
-               case 215:   /* stbx */
-               case 759:   /* stfdux */
-               case 727:   /* stfdx */
-               case 983:   /* stfiwx */
-               case 695:   /* stfsux */
-               case 663:   /* stfsx */
-               case 918:   /* sthbrx */
-               case 439:   /* sthux */
-               case 407:   /* sthx */
-               case 661:   /* stswx */
-               case 662:   /* stwbrx */
-               case 150:   /* stwcx. */
-               case 183:   /* stwux */
-               case 151:   /* stwx */
-               case 135:   /* stvebx */
-               case 167:   /* stvehx */
-               case 199:   /* stvewx */
-               case 231:   /* stvx */
-               case 487:   /* stvxl */
-                     tmp = EXTRACT_REGA(instr);
-                     if(tmp > 0)
-                        baseA = regs[tmp];
-                        baseB = regs[EXTRACT_REGC(instr)];
-                        /* determine Altivec alignment mask */
-                        switch(EXTRACT_OP2(instr)) {
-                           case 167:   /* stvehx */
-                                 alignmask = 0xFFFFFFFE;
-                                 break;
-                           case 199:   /* stvewx */
-                                 alignmask = 0xFFFFFFFC;
-                                 break;
-                           case 231:   /* stvx */
-                                 alignmask = 0xFFFFFFF0;
-                                 break;
-                           case 487:  /* stvxl */
-                                 alignmask = 0xFFFFFFF0;
-                                 break;
-                        }
-                        break;
-               case 725:   /* stswi */
-                     tmp = EXTRACT_REGA(instr);
-                     if(tmp > 0)
-                        baseA = regs[tmp];
-                        break;
-               default:   /* ignore instruction */
-#ifdef GC_DEBUG_DECODER
-                     GC_err_printf("Ignored by inner handler\n");
-#endif
-                     return NULL;
-                    break;
-            }
-            break;
-      default:   /* ignore instruction */
-#ifdef GC_DEBUG_DECODER
-            GC_err_printf("Ignored by main handler\n");
-#endif
-            return NULL;
-            break;
-   }
-       
-   addr = (baseA + baseB) + disp;
-  addr &= alignmask;
-#ifdef GC_DEBUG_DECODER
-   GC_err_printf1("BaseA: %d\n", baseA);
-   GC_err_printf1("BaseB: %d\n", baseB);
-   GC_err_printf1("Disp:  %d\n", disp);
-   GC_err_printf1("Address: %d\n", addr);
-#endif
-   return (char *)addr;
-}
-#endif /* MACOSX */
+# endif /* LINUX */
 
+#ifndef DARWIN
 SIG_PF GC_old_bus_handler;
 SIG_PF GC_old_segv_handler;    /* Also old MSWIN32 ACCESS_VIOLATION filter */
+#endif /* !DARWIN */
 
-#ifdef THREADS
+#if defined(THREADS)
 /* We need to lock around the bitmap update in the write fault handler */
 /* in order to avoid the risk of losing a bit.  We do this with a      */
 /* test-and-set spin lock if we know how to do that.  Otherwise we     */
@@ -2104,6 +2300,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #endif /* !THREADS */
 
 /*ARGSUSED*/
+#if !defined(DARWIN)
 # if defined (SUNOS4) || defined(FREEBSD)
     void GC_write_fault_handler(sig, code, scp, addr)
     int sig, code;
@@ -2119,7 +2316,8 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #     define SIG_OK (sig == SIGBUS)
 #     define CODE_OK (code == BUS_PAGE_FAULT)
 #   endif
-# endif
+# endif /* SUNOS4 || FREEBSD */
+
 # if defined(IRIX5) || defined(OSF1) || defined(HURD)
 #   include <errno.h>
     void GC_write_fault_handler(int sig, int code, struct sigcontext *scp)
@@ -2135,7 +2333,8 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #     define SIG_OK (sig == SIGBUS || sig == SIGSEGV)  
 #     define CODE_OK  TRUE
 #   endif
-# endif
+# endif /* IRIX5 || OSF1 || HURD */
+
 # if defined(LINUX)
 #   if defined(ALPHA) || defined(M68K)
       void GC_write_fault_handler(int sig, int code, s_c * sc)
@@ -2155,7 +2354,8 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
        /* Empirically c.trapno == 14, on IA32, but is that useful?     */
        /* Should probably consider alignment issues on other           */
        /* architectures.                                               */
-# endif
+# endif /* LINUX */
+
 # if defined(SUNOS5SIGS)
 #  ifdef __STDC__
     void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
@@ -2176,13 +2376,7 @@ SIG_PF GC_old_segv_handler;      /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #     define SIG_OK (sig == SIGSEGV)
 #     define CODE_OK (scp -> si_code == SEGV_ACCERR)
 #   endif
-# endif
-
-# if defined(MACOSX)
-    void GC_write_fault_handler(int sig, int code, struct sigcontext *scp)
-#   define SIG_OK (sig == SIGBUS)
-#   define CODE_OK (code == 0 /* experimentally determined */)
-# endif
+# endif /* SUNOS5SIGS */
 
 # if defined(MSWIN32) || defined(MSWINCE)
     LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info)
@@ -2190,7 +2384,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
                        STATUS_ACCESS_VIOLATION)
 #   define CODE_OK (exc_info -> ExceptionRecord -> ExceptionInformation[0] == 1)
                        /* Write fault */
-# endif
+# endif /* MSWIN32 || MSWINCE */
 {
     register unsigned i;
 #   if defined(HURD) 
@@ -2261,9 +2455,6 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #      endif
 #     endif
 #   endif
-#   if defined(MACOSX)
-        char * addr = get_fault_addr(scp);
-#   endif
 #   if defined(MSWIN32) || defined(MSWINCE)
        char * addr = (char *) (exc_info -> ExceptionRecord
                                -> ExceptionInformation[1]);
@@ -2327,9 +2518,6 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
                    (*(REAL_SIG_PF)old_handler) (sig, code, scp);
                    return;
 #              endif
-#              ifdef MACOSX
-                   (*(REAL_SIG_PF)old_handler) (sig, code, scp);
-#              endif
 #              ifdef MSWIN32
                    return((*old_handler)(exc_info));
 #              endif
@@ -2371,6 +2559,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
     ABORT("Unexpected bus error or segmentation fault");
 #endif
 }
+#endif /* !DARWIN */
 
 /*
  * We hold the allocation lock.  We expect block h to be written
@@ -2403,6 +2592,7 @@ GC_bool is_ptrfree;
     UNPROTECT(h_trunc, (ptr_t)h_end - (ptr_t)h_trunc);
 }
 
+#if !defined(DARWIN)
 void GC_dirty_init()
 {
 #   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) || \
@@ -2425,13 +2615,6 @@ void GC_dirty_init()
         (void)sigaddset(&act.sa_mask, SIG_SUSPEND);
 #     endif /* SIG_SUSPEND */
 #    endif
-#   if defined(MACOSX)
-      struct sigaction act, oldact;
-
-      act.sa_flags = SA_RESTART;
-      act.sa_handler = GC_write_fault_handler;
-      sigemptyset(&act.sa_mask);
-#   endif
 #   ifdef PRINTSTATS
        GC_printf0("Inititalizing mprotect virtual dirty bit implementation\n");
 #   endif
@@ -2471,7 +2654,10 @@ void GC_dirty_init()
        sigaction(SIGSEGV, 0, &oldact);
        sigaction(SIGSEGV, &act, 0);
 #     else
-       sigaction(SIGSEGV, &act, &oldact);
+       {
+         int res = sigaction(SIGSEGV, &act, &oldact);
+         if (res != 0) ABORT("Sigaction failed");
+       }
 #     endif
 #     if defined(_sigargs) || defined(HURD) || !defined(SA_SIGINFO)
        /* This is Irix 5.x, not 6.x.  Irix 5.x does not have   */
@@ -2494,7 +2680,7 @@ void GC_dirty_init()
 #       endif
       }
 #   endif
-#   if defined(MACOSX) || defined(HPUX) || defined(LINUX) || defined(HURD)
+#   if defined(HPUX) || defined(LINUX) || defined(HURD)
       sigaction(SIGBUS, &act, &oldact);
       GC_old_bus_handler = oldact.sa_handler;
       if (GC_old_bus_handler == SIG_IGN) {
@@ -2506,7 +2692,7 @@ void GC_dirty_init()
          GC_err_printf0("Replaced other SIGBUS handler\n");
 #       endif
       }
-#   endif /* MACOS || HPUX || LINUX */
+#   endif /* HPUX || LINUX || HURD */
 #   if defined(MSWIN32)
       GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
       if (GC_old_segv_handler != NULL) {
@@ -2518,6 +2704,7 @@ void GC_dirty_init()
       }
 #   endif
 }
+#endif /* !DARWIN */
 
 int GC_incremental_protection_needs()
 {
@@ -2767,13 +2954,6 @@ word n;
 {
 }
 
-# else /* !MPROTECT_VDB */
-
-#   ifdef GC_USE_LD_WRAP
-      ssize_t __wrap_read(int fd, void *buf, size_t nbyte)
-      { return __real_read(fd, buf, nbyte); }
-#   endif
-
 # endif /* MPROTECT_VDB */
 
 # ifdef PROC_VDB
@@ -2852,6 +3032,7 @@ void GC_dirty_init()
     }
     GC_proc_fd = syscall(SYS_ioctl, fd, PIOCOPENPD, 0);
     close(fd);
+    syscall(SYS_fcntl, GC_proc_fd, F_SETFD, FD_CLOEXEC);
     if (GC_proc_fd < 0) {
        ABORT("/proc ioctl failed");
     }
@@ -3091,6 +3272,552 @@ GC_bool is_ptrfree;
 
 # endif /* PCR_VDB */
 
+#if defined(MPROTECT_VDB) && defined(DARWIN)
+/* The following sources were used as a *reference* for this exception handling
+   code:
+      1. Apple's mach/xnu documentation
+      2. Timothy J. Wood's "Mach Exception Handlers 101" post to the
+         omnigroup's macosx-dev list. 
+         www.omnigroup.com/mailman/archive/macosx-dev/2000-June/002030.html
+      3. macosx-nat.c from Apple's GDB source code.
+*/
+   
+/* The bug that caused all this trouble should now be fixed. This should
+   eventually be removed if all goes well. */
+/* define BROKEN_EXCEPTION_HANDLING */
+    
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+#include <mach/thread_status.h>
+#include <mach/exception.h>
+#include <mach/task.h>
+#include <pthread.h>
+
+/* These are not defined in any header, although they are documented */
+extern boolean_t exc_server(mach_msg_header_t *,mach_msg_header_t *);
+extern kern_return_t exception_raise(
+    mach_port_t,mach_port_t,mach_port_t,
+    exception_type_t,exception_data_t,mach_msg_type_number_t);
+extern kern_return_t exception_raise_state(
+    mach_port_t,mach_port_t,mach_port_t,
+    exception_type_t,exception_data_t,mach_msg_type_number_t,
+    thread_state_flavor_t*,thread_state_t,mach_msg_type_number_t,
+    thread_state_t,mach_msg_type_number_t*);
+extern kern_return_t exception_raise_state_identity(
+    mach_port_t,mach_port_t,mach_port_t,
+    exception_type_t,exception_data_t,mach_msg_type_number_t,
+    thread_state_flavor_t*,thread_state_t,mach_msg_type_number_t,
+    thread_state_t,mach_msg_type_number_t*);
+
+
+#define MAX_EXCEPTION_PORTS 16
+
+static mach_port_t GC_task_self;
+
+static struct {
+    mach_msg_type_number_t count;
+    exception_mask_t      masks[MAX_EXCEPTION_PORTS];
+    exception_handler_t   ports[MAX_EXCEPTION_PORTS];
+    exception_behavior_t  behaviors[MAX_EXCEPTION_PORTS];
+    thread_state_flavor_t flavors[MAX_EXCEPTION_PORTS];
+} GC_old_exc_ports;
+
+static struct {
+    mach_port_t exception;
+#if defined(THREADS)
+    mach_port_t reply;
+#endif
+} GC_ports;
+
+typedef struct {
+    mach_msg_header_t head;
+} GC_msg_t;
+
+typedef enum {
+    GC_MP_NORMAL, GC_MP_DISCARDING, GC_MP_STOPPED
+} GC_mprotect_state_t;
+
+/* FIXME: 1 and 2 seem to be safe to use in the msgh_id field,
+   but it isn't  documented. Use the source and see if they
+   should be ok. */
+#define ID_STOP 1
+#define ID_RESUME 2
+
+/* These values are only used on the reply port */
+#define ID_ACK 3
+
+#if defined(THREADS)
+
+GC_mprotect_state_t GC_mprotect_state;
+
+/* The following should ONLY be called when the world is stopped  */
+static void GC_mprotect_thread_notify(mach_msg_id_t id) {
+    struct {
+        GC_msg_t msg;
+        mach_msg_trailer_t trailer;
+    } buf;
+    mach_msg_return_t r;
+    /* remote, local */
+    buf.msg.head.msgh_bits = 
+        MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,0);
+    buf.msg.head.msgh_size = sizeof(buf.msg);
+    buf.msg.head.msgh_remote_port = GC_ports.exception;
+    buf.msg.head.msgh_local_port = MACH_PORT_NULL;
+    buf.msg.head.msgh_id = id;
+            
+    r = mach_msg(
+        &buf.msg.head,
+        MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_LARGE,
+        sizeof(buf.msg),
+        sizeof(buf),
+        GC_ports.reply,
+        MACH_MSG_TIMEOUT_NONE,
+        MACH_PORT_NULL);
+    if(r != MACH_MSG_SUCCESS)
+       ABORT("mach_msg failed in GC_mprotect_thread_notify");
+    if(buf.msg.head.msgh_id != ID_ACK)
+        ABORT("invalid ack in GC_mprotect_thread_notify");
+}
+
+/* Should only be called by the mprotect thread */
+static void GC_mprotect_thread_reply() {
+    GC_msg_t msg;
+    mach_msg_return_t r;
+    /* remote, local */
+    msg.head.msgh_bits = 
+        MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,0);
+    msg.head.msgh_size = sizeof(msg);
+    msg.head.msgh_remote_port = GC_ports.reply;
+    msg.head.msgh_local_port = MACH_PORT_NULL;
+    msg.head.msgh_id = ID_ACK;
+            
+    r = mach_msg(
+        &msg.head,
+        MACH_SEND_MSG,
+        sizeof(msg),
+        0,
+        MACH_PORT_NULL,
+        MACH_MSG_TIMEOUT_NONE,
+        MACH_PORT_NULL);
+    if(r != MACH_MSG_SUCCESS)
+       ABORT("mach_msg failed in GC_mprotect_thread_reply");
+}
+
+void GC_mprotect_stop() {
+    GC_mprotect_thread_notify(ID_STOP);
+}
+void GC_mprotect_resume() {
+    GC_mprotect_thread_notify(ID_RESUME);
+}
+
+#else /* !THREADS */
+/* The compiler should optimize away any GC_mprotect_state computations */
+#define GC_mprotect_state GC_MP_NORMAL
+#endif
+
+static void *GC_mprotect_thread(void *arg) {
+    mach_msg_return_t r;
+    /* These two structures contain some private kernel data. We don't need to
+       access any of it so we don't bother defining a proper struct. The
+       correct definitions are in the xnu source code. */
+    struct {
+        mach_msg_header_t head;
+        char data[256];
+    } reply;
+    struct {
+        mach_msg_header_t head;
+        mach_msg_body_t msgh_body;
+        char data[1024];
+    } msg;
+
+    mach_msg_id_t id;
+    
+    for(;;) {
+        r = mach_msg(
+            &msg.head,
+            MACH_RCV_MSG|MACH_RCV_LARGE|
+                (GC_mprotect_state == GC_MP_DISCARDING ? MACH_RCV_TIMEOUT : 0),
+            0,
+            sizeof(msg),
+            GC_ports.exception,
+            GC_mprotect_state == GC_MP_DISCARDING ? 0 : MACH_MSG_TIMEOUT_NONE,
+            MACH_PORT_NULL);
+        
+        id = r == MACH_MSG_SUCCESS ? msg.head.msgh_id : -1;
+        
+#if defined(THREADS)
+        if(GC_mprotect_state == GC_MP_DISCARDING) {
+            if(r == MACH_RCV_TIMED_OUT) {
+                GC_mprotect_state = GC_MP_STOPPED;
+                GC_mprotect_thread_reply();
+                continue;
+            }
+            if(r == MACH_MSG_SUCCESS && (id == ID_STOP || id == ID_RESUME))
+                ABORT("out of order mprotect thread request");
+        }
+#endif
+        
+        if(r != MACH_MSG_SUCCESS) {
+            GC_err_printf2("mach_msg failed with %d %s\n", 
+                (int)r,mach_error_string(r));
+            ABORT("mach_msg failed");
+        }
+        
+        switch(id) {
+#if defined(THREADS)
+            case ID_STOP:
+                if(GC_mprotect_state != GC_MP_NORMAL)
+                    ABORT("Called mprotect_stop when state wasn't normal");
+                GC_mprotect_state = GC_MP_DISCARDING;
+                break;
+            case ID_RESUME:
+                if(GC_mprotect_state != GC_MP_STOPPED)
+                    ABORT("Called mprotect_resume when state wasn't stopped");
+                GC_mprotect_state = GC_MP_NORMAL;
+                GC_mprotect_thread_reply();
+                break;
+#endif /* THREADS */
+            default:
+                   /* Handle the message (calls catch_exception_raise) */
+               if(!exc_server(&msg.head,&reply.head))
+                    ABORT("exc_server failed");
+                /* Send the reply */
+                r = mach_msg(
+                    &reply.head,
+                    MACH_SEND_MSG,
+                    reply.head.msgh_size,
+                    0,
+                    MACH_PORT_NULL,
+                    MACH_MSG_TIMEOUT_NONE,
+                    MACH_PORT_NULL);
+               if(r != MACH_MSG_SUCCESS) {
+                       /* This will fail if the thread dies, but the thread shouldn't
+                          die... */
+                       #ifdef BROKEN_EXCEPTION_HANDLING
+                       GC_err_printf2(
+                        "mach_msg failed with %d %s while sending exc reply\n",
+                        (int)r,mach_error_string(r));
+               #else
+                       ABORT("mach_msg failed while sending exception reply");
+               #endif
+               }
+        } /* switch */
+    } /* for(;;) */
+    /* NOT REACHED */
+    return NULL;
+}
+
+/* All this SIGBUS code shouldn't be necessary. All protection faults should
+   be going throught the mach exception handler. However, it seems a SIGBUS is
+   occasionally sent for some unknown reason. Even more odd, it seems to be
+   meaningless and safe to ignore. */
+#ifdef BROKEN_EXCEPTION_HANDLING
+
+typedef void (* SIG_PF)();
+static SIG_PF GC_old_bus_handler;
+
+/* Updates to this aren't atomic, but the SIGBUSs seem pretty rare.
+   Even if this doesn't get updated property, it isn't really a problem */
+static int GC_sigbus_count;
+
+static void GC_darwin_sigbus(int num,siginfo_t *sip,void *context) {
+    if(num != SIGBUS) ABORT("Got a non-sigbus signal in the sigbus handler");
+    
+    /* Ugh... some seem safe to ignore, but too many in a row probably means
+       trouble. GC_sigbus_count is reset for each mach exception that is
+       handled */
+    if(GC_sigbus_count >= 8) {
+        ABORT("Got more than 8 SIGBUSs in a row!");
+    } else {
+        GC_sigbus_count++;
+        GC_err_printf0("GC: WARNING: Ignoring SIGBUS.\n");
+    }
+}
+#endif /* BROKEN_EXCEPTION_HANDLING */
+
+void GC_dirty_init() {
+    kern_return_t r;
+    mach_port_t me;
+    pthread_t thread;
+    pthread_attr_t attr;
+    exception_mask_t mask;
+    
+#   ifdef PRINTSTATS
+        GC_printf0("Inititalizing mach/darwin mprotect virtual dirty bit "
+            "implementation\n");
+#   endif  
+#      ifdef BROKEN_EXCEPTION_HANDLING
+        GC_err_printf0("GC: WARNING: Enabling workarounds for various darwin "
+            "exception handling bugs.\n");
+#      endif
+    GC_dirty_maintained = TRUE;
+    if (GC_page_size % HBLKSIZE != 0) {
+        GC_err_printf0("Page size not multiple of HBLKSIZE\n");
+        ABORT("Page size not multiple of HBLKSIZE");
+    }
+    
+    GC_task_self = me = mach_task_self();
+    
+    r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&GC_ports.exception);
+    if(r != KERN_SUCCESS) ABORT("mach_port_allocate failed (exception port)");
+    
+    r = mach_port_insert_right(me,GC_ports.exception,GC_ports.exception,
+       MACH_MSG_TYPE_MAKE_SEND);
+    if(r != KERN_SUCCESS)
+       ABORT("mach_port_insert_right failed (exception port)");
+
+    #if defined(THREADS)
+        r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&GC_ports.reply);
+        if(r != KERN_SUCCESS) ABORT("mach_port_allocate failed (reply port)");
+    #endif
+
+    /* The exceptions we want to catch */  
+    mask = EXC_MASK_BAD_ACCESS;
+
+    r = task_get_exception_ports(
+        me,
+        mask,
+        GC_old_exc_ports.masks,
+        &GC_old_exc_ports.count,
+        GC_old_exc_ports.ports,
+        GC_old_exc_ports.behaviors,
+        GC_old_exc_ports.flavors
+    );
+    if(r != KERN_SUCCESS) ABORT("task_get_exception_ports failed");
+        
+    r = task_set_exception_ports(
+        me,
+        mask,
+        GC_ports.exception,
+        EXCEPTION_DEFAULT,
+        MACHINE_THREAD_STATE
+    );
+    if(r != KERN_SUCCESS) ABORT("task_set_exception_ports failed");
+
+    if(pthread_attr_init(&attr) != 0) ABORT("pthread_attr_init failed");
+    if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED) != 0) 
+        ABORT("pthread_attr_setdetachedstate failed");
+
+#      undef pthread_create
+    /* This will call the real pthread function, not our wrapper */
+    if(pthread_create(&thread,&attr,GC_mprotect_thread,NULL) != 0)
+        ABORT("pthread_create failed");
+    pthread_attr_destroy(&attr);
+    
+    /* Setup the sigbus handler for ignoring the meaningless SIGBUSs */
+    #ifdef BROKEN_EXCEPTION_HANDLING 
+    {
+        struct sigaction sa, oldsa;
+        sa.sa_handler = (SIG_PF)GC_darwin_sigbus;
+        sigemptyset(&sa.sa_mask);
+        sa.sa_flags = SA_RESTART|SA_SIGINFO;
+        if(sigaction(SIGBUS,&sa,&oldsa) < 0) ABORT("sigaction");
+        GC_old_bus_handler = (SIG_PF)oldsa.sa_handler;
+        if (GC_old_bus_handler != SIG_DFL) {
+#              ifdef PRINTSTATS
+                GC_err_printf0("Replaced other SIGBUS handler\n");
+#              endif
+        }
+    }
+    #endif /* BROKEN_EXCEPTION_HANDLING  */
+}
+/* The source code for Apple's GDB was used as a reference for the exception
+   forwarding code. This code is similar to be GDB code only because there is 
+   only one way to do it. */
+static kern_return_t GC_forward_exception(
+        mach_port_t thread,
+        mach_port_t task,
+        exception_type_t exception,
+        exception_data_t data,
+        mach_msg_type_number_t data_count
+) {
+    int i;
+    kern_return_t r;
+    mach_port_t port;
+    exception_behavior_t behavior;
+    thread_state_flavor_t flavor;
+    
+    thread_state_data_t thread_state;
+    mach_msg_type_number_t thread_state_count = THREAD_STATE_MAX;
+        
+    for(i=0;i<GC_old_exc_ports.count;i++)
+        if(GC_old_exc_ports.masks[i] & (1 << exception))
+            break;
+    if(i==GC_old_exc_ports.count) ABORT("No handler for exception!");
+    
+    port = GC_old_exc_ports.ports[i];
+    behavior = GC_old_exc_ports.behaviors[i];
+    flavor = GC_old_exc_ports.flavors[i];
+
+    if(behavior != EXCEPTION_DEFAULT) {
+        r = thread_get_state(thread,flavor,thread_state,&thread_state_count);
+        if(r != KERN_SUCCESS)
+            ABORT("thread_get_state failed in forward_exception");
+    }
+    
+    switch(behavior) {
+        case EXCEPTION_DEFAULT:
+            r = exception_raise(port,thread,task,exception,data,data_count);
+            break;
+        case EXCEPTION_STATE:
+            r = exception_raise_state(port,thread,task,exception,data,
+                data_count,&flavor,thread_state,thread_state_count,
+                thread_state,&thread_state_count);
+            break;
+        case EXCEPTION_STATE_IDENTITY:
+            r = exception_raise_state_identity(port,thread,task,exception,data,
+                data_count,&flavor,thread_state,thread_state_count,
+                thread_state,&thread_state_count);
+            break;
+        default:
+            r = KERN_FAILURE; /* make gcc happy */
+            ABORT("forward_exception: unknown behavior");
+            break;
+    }
+    
+    if(behavior != EXCEPTION_DEFAULT) {
+        r = thread_set_state(thread,flavor,thread_state,thread_state_count);
+        if(r != KERN_SUCCESS)
+            ABORT("thread_set_state failed in forward_exception");
+    }
+    
+    return r;
+}
+
+#define FWD() GC_forward_exception(thread,task,exception,code,code_count)
+
+/* This violates the namespace rules but there isn't anything that can be done
+   about it. The exception handling stuff is hard coded to call this */
+kern_return_t
+catch_exception_raise(
+   mach_port_t exception_port,mach_port_t thread,mach_port_t task,
+   exception_type_t exception,exception_data_t code,
+   mach_msg_type_number_t code_count
+) {
+    kern_return_t r;
+    char *addr;
+    struct hblk *h;
+    int i;
+#ifdef POWERPC
+    thread_state_flavor_t flavor = PPC_EXCEPTION_STATE;
+    mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE_COUNT;
+    ppc_exception_state_t exc_state;
+#else
+#      error FIXME for non-ppc darwin
+#endif
+
+    
+    if(exception != EXC_BAD_ACCESS || code[0] != KERN_PROTECTION_FAILURE) {
+        #ifdef DEBUG_EXCEPTION_HANDLING
+        /* We aren't interested, pass it on to the old handler */
+        GC_printf3("Exception: 0x%x Code: 0x%x 0x%x in catch....\n",
+            exception,
+            code_count > 0 ? code[0] : -1,
+            code_count > 1 ? code[1] : -1); 
+        #endif
+        return FWD();
+    }
+
+    r = thread_get_state(thread,flavor,
+        (natural_t*)&exc_state,&exc_state_count);
+    if(r != KERN_SUCCESS) {
+        /* The thread is supposed to be suspended while the exception handler
+           is called. This shouldn't fail. */
+        #ifdef BROKEN_EXCEPTION_HANDLING
+            GC_err_printf0("thread_get_state failed in "
+                "catch_exception_raise\n");
+            return KERN_SUCCESS;
+        #else
+            ABORT("thread_get_state failed in catch_exception_raise");
+        #endif
+    }
+    
+    /* This is the address that caused the fault */
+    addr = (char*) exc_state.dar;
+        
+    if((HDR(addr)) == 0) {
+        /* Ugh... just like the SIGBUS problem above, it seems we get a bogus 
+           KERN_PROTECTION_FAILURE every once and a while. We wait till we get
+           a bunch in a row before doing anything about it. If a "real" fault 
+           ever occurres it'll just keep faulting over and over and we'll hit
+           the limit pretty quickly. */
+        #ifdef BROKEN_EXCEPTION_HANDLING
+            static char *last_fault;
+            static int last_fault_count;
+            
+            if(addr != last_fault) {
+                last_fault = addr;
+                last_fault_count = 0;
+            }
+            if(++last_fault_count < 32) {
+                if(last_fault_count == 1)
+                    GC_err_printf1(
+                        "GC: WARNING: Ignoring KERN_PROTECTION_FAILURE at %p\n",
+                        addr);
+                return KERN_SUCCESS;
+            }
+            
+            GC_err_printf1("Unexpected KERN_PROTECTION_FAILURE at %p\n",addr);
+            /* Can't pass it along to the signal handler because that is
+               ignoring SIGBUS signals. We also shouldn't call ABORT here as
+               signals don't always work too well from the exception handler. */
+            GC_err_printf0("Aborting\n");
+            exit(EXIT_FAILURE);
+        #else /* BROKEN_EXCEPTION_HANDLING */
+            /* Pass it along to the next exception handler 
+               (which should call SIGBUS/SIGSEGV) */
+            return FWD();
+        #endif /* !BROKEN_EXCEPTION_HANDLING */
+    }
+
+    #ifdef BROKEN_EXCEPTION_HANDLING
+        /* Reset the number of consecutive SIGBUSs */
+        GC_sigbus_count = 0;
+    #endif
+    
+    if(GC_mprotect_state == GC_MP_NORMAL) { /* common case */
+        h = (struct hblk*)((word)addr & ~(GC_page_size-1));
+        UNPROTECT(h, GC_page_size);    
+        for (i = 0; i < divHBLKSZ(GC_page_size); i++) {
+            register int index = PHT_HASH(h+i);
+            async_set_pht_entry_from_index(GC_dirty_pages, index);
+        }
+    } else if(GC_mprotect_state == GC_MP_DISCARDING) {
+        /* Lie to the thread for now. No sense UNPROTECT()ing the memory
+           when we're just going to PROTECT() it again later. The thread
+           will just fault again once it resumes */
+    } else {
+        /* Shouldn't happen, i don't think */
+        GC_printf0("KERN_PROTECTION_FAILURE while world is stopped\n");
+        return FWD();
+    }
+    return KERN_SUCCESS;
+}
+#undef FWD
+
+/* These should never be called, but just in case...  */
+kern_return_t catch_exception_raise_state(mach_port_name_t exception_port,
+    int exception, exception_data_t code, mach_msg_type_number_t codeCnt,
+    int flavor, thread_state_t old_state, int old_stateCnt,
+    thread_state_t new_state, int new_stateCnt)
+{
+    ABORT("catch_exception_raise_state");
+    return(KERN_INVALID_ARGUMENT);
+}
+kern_return_t catch_exception_raise_state_identity(
+    mach_port_name_t exception_port, mach_port_t thread, mach_port_t task,
+    int exception, exception_data_t code, mach_msg_type_number_t codeCnt,
+    int flavor, thread_state_t old_state, int old_stateCnt, 
+    thread_state_t new_state, int new_stateCnt)
+{
+    ABORT("catch_exception_raise_state_identity");
+    return(KERN_INVALID_ARGUMENT);
+}
+
+
+#endif /* DARWIN && MPROTECT_VDB */
+
 # ifndef HAVE_INCREMENTAL_PROTECTION_NEEDS
   int GC_incremental_protection_needs()
   {
@@ -3155,17 +3882,6 @@ GC_bool is_ptrfree;
 /* Fill in the pc and argument information for up to NFRAMES of my     */
 /* callers.  Ignore my frame and my callers frame.                     */
 
-#ifdef LINUX
-# include <features.h>
-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2
-#   define HAVE_BUILTIN_BACKTRACE
-#   ifdef IA64
-#     define BUILTIN_BACKTRACE_BROKEN
-#   endif
-# endif
-#endif
-
-#include <execinfo.h>
 #ifdef LINUX
 #   include <unistd.h>
 #endif
@@ -3175,7 +3891,9 @@ GC_bool is_ptrfree;
 #ifdef SAVE_CALL_CHAIN
 
 #if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \
-    && defined(HAVE_BUILTIN_BACKTRACE)
+    && defined(GC_HAVE_BUILTIN_BACKTRACE)
+
+#include <execinfo.h>
 
 void GC_save_callers (info) 
 struct callinfo info[NFRAMES];
@@ -3219,8 +3937,6 @@ struct callinfo info[NFRAMES];
     asm("movl %%ebp,%0" : "=r"(frame));
     fp = frame;
 # else
-    word GC_save_regs_in_stack();
-
     frame = (struct frame *) GC_save_regs_in_stack ();
     fp = (struct frame *)((long) frame -> FR_SAVFP + BIAS);
 #endif
@@ -3288,8 +4004,7 @@ struct callinfo info[NFRAMES];
 #        ifdef LINUX
            FILE *pipe;
 #        endif
-#        if defined(HAVE_BUILTIN_BACKTRACE) && \
-            !defined(BUILTIN_BACKTRACE_BROKEN)
+#        if defined(GC_HAVE_BUILTIN_BACKTRACE)
            char **sym_name =
              backtrace_symbols((void **)(&(info[i].ci_pc)), 1);
            char *name = sym_name[0];
@@ -3362,12 +4077,11 @@ struct callinfo info[NFRAMES];
                }
                name = result_buf;
                pclose(pipe);
-               out:
+               out:;
            }
 #        endif /* LINUX */
          GC_err_printf1("\t\t%s\n", name);
-#        if defined(HAVE_BUILTIN_BACKTRACE) && \
-            !defined(BUILTIN_BACKTRACE_BROKEN)
+#        if defined(GC_HAVE_BUILTIN_BACKTRACE)
            free(sym_name);  /* May call GC_free; that's OK */
 #         endif
        }
@@ -3379,31 +4093,6 @@ struct callinfo info[NFRAMES];
 
 #endif /* NEED_CALLINFO */
 
-#if defined(LINUX) && defined(__ELF__) && \
-    (!defined(SMALL_CONFIG) || defined(USE_PROC_FOR_LIBRARIES))
-#ifdef GC_USE_LD_WRAP
-#   define READ __real_read
-#else
-#   define READ read
-#endif
-
-
-/* Repeatedly perform a read call until the buffer is filled or        */
-/* we encounter EOF.                                           */
-ssize_t GC_repeat_read(int fd, char *buf, size_t count)
-{
-    ssize_t num_read = 0;
-    ssize_t result;
-    
-    while (num_read < count) {
-       result = READ(fd, buf + num_read, count - num_read);
-       if (result < 0) return result;
-       if (result == 0) break;
-       num_read += result;
-    }
-    return num_read;
-}
-#endif /* LINUX && ... */
 
 
 #if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
@@ -3411,20 +4100,16 @@ ssize_t GC_repeat_read(int fd, char *buf, size_t count)
 /* Dump /proc/self/maps to GC_stderr, to enable looking up names for
    addresses in FIND_LEAK output. */
 
+static word dump_maps(char *maps)
+{
+    GC_err_write(maps, strlen(maps));
+    return 1;
+}
+
 void GC_print_address_map()
 {
-    int f;
-    int result;
-    char maps_temp[32768];
     GC_err_printf0("---------- Begin address map ----------\n");
-        f = open("/proc/self/maps", O_RDONLY);
-        if (-1 == f) ABORT("Couldn't open /proc/self/maps");
-       do {
-           result = GC_repeat_read(f, maps_temp, sizeof(maps_temp));
-           if (result <= 0) ABORT("Couldn't read /proc/self/maps");
-           GC_err_write(maps_temp, result);
-       } while (result == sizeof(maps_temp));
-     
+    GC_apply_to_maps(dump_maps);
     GC_err_printf0("---------- End address map ----------\n");
 }
 
diff --git a/powerpc_darwin_mach_dep.s b/powerpc_darwin_mach_dep.s
new file mode 100644 (file)
index 0000000..92f2c93
--- /dev/null
@@ -0,0 +1,84 @@
+
+; GC_push_regs function. Under some optimization levels GCC will clobber
+; some of the non-volatile registers before we get a chance to save them
+; therefore, this can't be inline asm.
+
+.text
+       .align 2
+       .globl _GC_push_regs
+_GC_push_regs:
+    
+    ; Prolog
+       mflr r0
+       stw r0,8(r1)
+       stwu r1,-80(r1)
+
+       ; Push r13-r31
+       mr r3,r13
+       bl L_GC_push_one$stub
+       mr r3,r14
+       bl L_GC_push_one$stub
+       mr r3,r15
+       bl L_GC_push_one$stub
+       mr r3,r16
+       bl L_GC_push_one$stub
+       mr r3,r17
+       bl L_GC_push_one$stub
+       mr r3,r18
+       bl L_GC_push_one$stub
+       mr r3,r19
+       bl L_GC_push_one$stub
+       mr r3,r20
+       bl L_GC_push_one$stub
+       mr r3,r21
+       bl L_GC_push_one$stub
+       mr r3,r22
+       bl L_GC_push_one$stub
+       mr r3,r23
+       bl L_GC_push_one$stub
+       mr r3,r24
+       bl L_GC_push_one$stub
+       mr r3,r25
+       bl L_GC_push_one$stub
+       mr r3,r26
+       bl L_GC_push_one$stub
+       mr r3,r27
+       bl L_GC_push_one$stub
+       mr r3,r28
+       bl L_GC_push_one$stub
+       mr r3,r29
+       bl L_GC_push_one$stub
+       mr r3,r30
+       bl L_GC_push_one$stub
+       mr r3,r31
+       bl L_GC_push_one$stub
+
+    ; 
+    lwz r0,88(r1)
+    addi r1,r1,80
+       mtlr r0
+       
+       ; Return
+       blr
+
+; PIC stuff, generated by GCC
+
+.data
+.picsymbol_stub
+L_GC_push_one$stub:
+       .indirect_symbol _GC_push_one
+       mflr r0
+       bcl 20,31,L0$_GC_push_one
+L0$_GC_push_one:
+       mflr r11
+       addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
+       mtlr r0
+       lwz r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
+       mtctr r12
+       addi r11,r11,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
+       bctr
+.data
+.lazy_symbol_pointer
+L_GC_push_one$lazy_ptr:
+       .indirect_symbol _GC_push_one
+       .long dyld_stub_binding_helper
diff --git a/powerpc_macosx_mach_dep.s b/powerpc_macosx_mach_dep.s
deleted file mode 100755 (executable)
index 92f0628..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-       
-.text
-    
-    .set   linkageArea,24
-    .set   params,4
-    .set   alignment,4
-
-    .set   spaceToSave,linkageArea+params+alignment
-    .set   spaceToSave8,spaceToSave+8
-
-; Mark from machine registers that are saved by C compiler
-    .globl  _GC_push_regs
-_GC_push_regs:
-    ; PROLOG
-    mflr    r0          ; get return address
-    stw     r0,8(r1)    ; save return address
-    stwu    r1,-spaceToSave(r1)   ; skip over caller save area
-    ;
-    mr      r3,r2         ; mark from r2. Well Im not really sure
-                          ; that this is necessary or even the right
-                          ; thing to do - at least it doesnt harm...
-                          ; According to Apples docs it points to
-                          ; the direct data area, whatever that is...
-    bl             L_GC_push_one$stub
-    mr      r3,r13        ; mark from r13-r31
-    bl             L_GC_push_one$stub
-    mr      r3,r14
-    bl             L_GC_push_one$stub
-    mr      r3,r15
-    bl             L_GC_push_one$stub
-    mr      r3,r16
-    bl             L_GC_push_one$stub
-    mr      r3,r17
-    bl             L_GC_push_one$stub
-    mr      r3,r18
-    bl             L_GC_push_one$stub
-    mr      r3,r19
-    bl             L_GC_push_one$stub
-    mr      r3,r20
-    bl             L_GC_push_one$stub
-    mr      r3,r21
-    bl             L_GC_push_one$stub
-    mr      r3,r22
-    bl             L_GC_push_one$stub
-    mr      r3,r23
-    bl             L_GC_push_one$stub
-    mr      r3,r24
-    bl             L_GC_push_one$stub
-    mr      r3,r25
-    bl             L_GC_push_one$stub
-    mr      r3,r26
-    bl             L_GC_push_one$stub
-    mr      r3,r27
-    bl             L_GC_push_one$stub
-    mr      r3,r28
-    bl             L_GC_push_one$stub
-    mr      r3,r29
-    bl             L_GC_push_one$stub
-    mr      r3,r30
-    bl             L_GC_push_one$stub
-    mr      r3,r31
-    bl             L_GC_push_one$stub
-    ; EPILOG
-    lwz     r0,spaceToSave8(r1)   ; get return address back
-    mtlr    r0    ; reset link register
-    addic   r1,r1,spaceToSave   ; restore stack pointer
-    blr
-
-.data
-.picsymbol_stub
-L_GC_push_one$stub:
-       .indirect_symbol _GC_push_one
-       mflr r0
-       bcl 20,31,L0$_GC_push_one
-L0$_GC_push_one:
-       mflr r11
-       addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
-       mtlr r0
-       lwz r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
-       mtctr r12
-       addi r11,r11,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
-       bctr
-.data
-.lazy_symbol_pointer
-L_GC_push_one$lazy_ptr:
-       .indirect_symbol _GC_push_one
-       .long dyld_stub_binding_helper
-.non_lazy_symbol_pointer
-L_GC_push_one$non_lazy_ptr:
-       .indirect_symbol _GC_push_one
-       .long 0
-       
-
-
-
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
new file mode 100644 (file)
index 0000000..5dfd26d
--- /dev/null
@@ -0,0 +1,445 @@
+#include "private/pthread_support.h"
+
+#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+     && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \
+     && !defined(GC_DARWIN_THREADS) && !defined(GC_AIX_THREADS)
+
+#include <signal.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <unistd.h>
+
+#if DEBUG_THREADS
+
+#ifndef NSIG
+# if defined(MAXSIG)
+#  define NSIG (MAXSIG+1)
+# elif defined(_NSIG)
+#  define NSIG _NSIG
+# elif defined(__SIGRTMAX)
+#  define NSIG (__SIGRTMAX+1)
+# else
+  --> please fix it
+# endif
+#endif
+
+void GC_print_sig_mask()
+{
+    sigset_t blocked;
+    int i;
+
+    if (pthread_sigmask(SIG_BLOCK, NULL, &blocked) != 0)
+       ABORT("pthread_sigmask");
+    GC_printf0("Blocked: ");
+    for (i = 1; i < NSIG; i++) {
+        if (sigismember(&blocked, i)) { GC_printf1("%ld ",(long) i); }
+    }
+    GC_printf0("\n");
+}
+
+#endif
+
+word GC_stop_count;    /* Incremented at the beginning of GC_stop_world. */
+
+#ifdef GC_OSF1_THREADS
+  GC_bool GC_retry_signals = TRUE;
+#else
+  GC_bool GC_retry_signals = FALSE;
+#endif
+
+/*
+ * We use signals to stop threads during GC.
+ * 
+ * Suspended threads wait in signal handler for SIG_THR_RESTART.
+ * That's more portable than semaphores or condition variables.
+ * (We do use sem_post from a signal handler, but that should be portable.)
+ *
+ * The thread suspension signal SIG_SUSPEND is now defined in gc_priv.h.
+ * Note that we can't just stop a thread; we need it to save its stack
+ * pointer(s) and acknowledge.
+ */
+
+#ifndef SIG_THR_RESTART
+#  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+#    ifdef _SIGRTMIN
+#      define SIG_THR_RESTART _SIGRTMIN + 5
+#    else
+#      define SIG_THR_RESTART SIGRTMIN + 5
+#    endif
+#  else
+#   define SIG_THR_RESTART SIGXCPU
+#  endif
+#endif
+
+sem_t GC_suspend_ack_sem;
+
+void GC_suspend_handler(int sig)
+{
+    int dummy;
+    pthread_t my_thread = pthread_self();
+    GC_thread me;
+    sigset_t mask;
+#   ifdef PARALLEL_MARK
+       word my_mark_no = GC_mark_no;
+       /* Marker can't proceed until we acknowledge.  Thus this is     */
+       /* guaranteed to be the mark_no correspending to our            */
+       /* suspension, i.e. the marker can't have incremented it yet.   */
+#   endif
+    word my_stop_count = GC_stop_count;
+
+    if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
+
+#if DEBUG_THREADS
+    GC_printf1("Suspending 0x%lx\n", my_thread);
+#endif
+
+    me = GC_lookup_thread(my_thread);
+    /* The lookup here is safe, since I'm doing this on behalf  */
+    /* of a thread which holds the allocation lock in order    */
+    /* to stop the world.  Thus concurrent modification of the */
+    /* data structure is impossible.                           */
+    if (me -> stop_info.last_stop_count == my_stop_count) {
+       /* Duplicate signal.  OK if we are retrying.    */
+       if (!GC_retry_signals) {
+           WARN("Duplicate suspend signal in thread %lx\n",
+                pthread_self());
+       }
+       return;
+    }
+#   ifdef SPARC
+       me -> stop_info.stack_ptr = (ptr_t)GC_save_regs_in_stack();
+#   else
+       me -> stop_info.stack_ptr = (ptr_t)(&dummy);
+#   endif
+#   ifdef IA64
+       me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack();
+#   endif
+
+    /* Tell the thread that wants to stop the world that this   */
+    /* thread has been stopped.  Note that sem_post() is       */
+    /* the only async-signal-safe primitive in LinuxThreads.    */
+    sem_post(&GC_suspend_ack_sem);
+    me -> stop_info.last_stop_count = my_stop_count;
+
+    /* Wait until that thread tells us to restart by sending    */
+    /* this thread a SIG_THR_RESTART signal.                   */
+    /* SIG_THR_RESTART should be masked at this point.  Thus there     */
+    /* is no race.                                             */
+    if (sigfillset(&mask) != 0) ABORT("sigfillset() failed");
+    if (sigdelset(&mask, SIG_THR_RESTART) != 0) ABORT("sigdelset() failed");
+#   ifdef NO_SIGNALS
+      if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
+      if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
+      if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
+      if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
+#   endif
+    do {
+           me->stop_info.signal = 0;
+           sigsuspend(&mask);             /* Wait for signal */
+    } while (me->stop_info.signal != SIG_THR_RESTART);
+    /* If the RESTART signal gets lost, we can still lose.  That should be  */
+    /* less likely than losing the SUSPEND signal, since we don't do much   */
+    /* between the sem_post and sigsuspend.                                */
+    /* We'd need more handshaking to work around that, since we don't want  */
+    /* to accidentally leave a RESTART signal pending, thus causing us to   */
+    /* continue prematurely in a future round.                             */ 
+
+#if DEBUG_THREADS
+    GC_printf1("Continuing 0x%lx\n", my_thread);
+#endif
+}
+
+void GC_restart_handler(int sig)
+{
+    pthread_t my_thread = pthread_self();
+    GC_thread me;
+
+    if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
+
+    /* Let the GC_suspend_handler() know that we got a SIG_THR_RESTART. */
+    /* The lookup here is safe, since I'm doing this on behalf  */
+    /* of a thread which holds the allocation lock in order    */
+    /* to stop the world.  Thus concurrent modification of the */
+    /* data structure is impossible.                           */
+    me = GC_lookup_thread(my_thread);
+    me->stop_info.signal = SIG_THR_RESTART;
+
+    /*
+    ** Note: even if we didn't do anything useful here,
+    ** it would still be necessary to have a signal handler,
+    ** rather than ignoring the signals, otherwise
+    ** the signals will not be delivered at all, and
+    ** will thus not interrupt the sigsuspend() above.
+    */
+
+#if DEBUG_THREADS
+    GC_printf1("In GC_restart_handler for 0x%lx\n", pthread_self());
+#endif
+}
+
+# ifdef IA64
+#   define IF_IA64(x) x
+# else
+#   define IF_IA64(x)
+# endif
+/* We hold allocation lock.  Should do exactly the right thing if the  */
+/* world is stopped.  Should not fail if it isn't.                     */
+void GC_push_all_stacks()
+{
+    int i;
+    GC_thread p;
+    ptr_t lo, hi;
+    /* On IA64, we also need to scan the register backing store. */
+    IF_IA64(ptr_t bs_lo; ptr_t bs_hi;)
+    pthread_t me = pthread_self();
+    
+    if (!GC_thr_initialized) GC_thr_init();
+    #if DEBUG_THREADS
+        GC_printf1("Pushing stacks from thread 0x%lx\n", (unsigned long) me);
+    #endif
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+      for (p = GC_threads[i]; p != 0; p = p -> next) {
+        if (p -> flags & FINISHED) continue;
+        if (pthread_equal(p -> id, me)) {
+#          ifdef SPARC
+               lo = (ptr_t)GC_save_regs_in_stack();
+#          else
+               lo = GC_approx_sp();
+#           endif
+           IF_IA64(bs_hi = (ptr_t)GC_save_regs_in_stack();)
+       } else {
+           lo = p -> stop_info.stack_ptr;
+           IF_IA64(bs_hi = p -> backing_store_ptr;)
+       }
+        if ((p -> flags & MAIN_THREAD) == 0) {
+           hi = p -> stack_end;
+           IF_IA64(bs_lo = p -> backing_store_end);
+        } else {
+            /* The original stack. */
+            hi = GC_stackbottom;
+           IF_IA64(bs_lo = BACKING_STORE_BASE;)
+        }
+        #if DEBUG_THREADS
+            GC_printf3("Stack for thread 0x%lx = [%lx,%lx)\n",
+               (unsigned long) p -> id,
+               (unsigned long) lo, (unsigned long) hi);
+        #endif
+       if (0 == lo) ABORT("GC_push_all_stacks: sp not set!\n");
+#       ifdef STACK_GROWS_UP
+         /* We got them backwards! */
+          GC_push_all_stack(hi, lo);
+#       else
+          GC_push_all_stack(lo, hi);
+#      endif
+#      ifdef IA64
+          if (pthread_equal(p -> id, me)) {
+           GC_push_all_eager(bs_lo, bs_hi);
+         } else {
+           GC_push_all_stack(bs_lo, bs_hi);
+         }
+#      endif
+      }
+    }
+}
+
+/* There seems to be a very rare thread stopping problem.  To help us  */
+/* debug that, we save the ids of the stopping thread. */
+pthread_t GC_stopping_thread;
+int GC_stopping_pid;
+
+/* We hold the allocation lock.  Suspend all threads that might        */
+/* still be running.  Return the number of suspend signals that        */
+/* were sent. */
+int GC_suspend_all()
+{
+    int n_live_threads = 0;
+    int i;
+    GC_thread p;
+    int result;
+    pthread_t my_thread = pthread_self();
+    
+    GC_stopping_thread = my_thread;    /* debugging only.      */
+    GC_stopping_pid = getpid();                /* debugging only.      */
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+      for (p = GC_threads[i]; p != 0; p = p -> next) {
+        if (p -> id != my_thread) {
+            if (p -> flags & FINISHED) continue;
+            if (p -> stop_info.last_stop_count == GC_stop_count) continue;
+           if (p -> thread_blocked) /* Will wait */ continue;
+            n_live_threads++;
+           #if DEBUG_THREADS
+             GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
+           #endif
+        
+        result = pthread_kill(p -> id, SIG_SUSPEND);
+           switch(result) {
+                case ESRCH:
+                    /* Not really there anymore.  Possible? */
+                    n_live_threads--;
+                    break;
+                case 0:
+                    break;
+                default:
+                    ABORT("pthread_kill failed");
+            }
+        }
+      }
+    }
+    return n_live_threads;
+}
+
+/* Caller holds allocation lock.       */
+void GC_stop_world()
+{
+    int i;
+    int n_live_threads;
+    int code;
+
+    #if DEBUG_THREADS
+    GC_printf1("Stopping the world from 0x%lx\n", pthread_self());
+    #endif
+       
+    /* Make sure all free list construction has stopped before we start. */
+    /* No new construction can start, since free list construction is  */
+    /* required to acquire and release the GC lock before it starts,   */
+    /* and we have the lock.                                           */
+#   ifdef PARALLEL_MARK
+      GC_acquire_mark_lock();
+      GC_ASSERT(GC_fl_builder_count == 0);
+      /* We should have previously waited for it to become zero. */
+#   endif /* PARALLEL_MARK */
+    ++GC_stop_count;
+    n_live_threads = GC_suspend_all();
+
+      if (GC_retry_signals) {
+         unsigned long wait_usecs = 0;  /* Total wait since retry.     */
+#        define WAIT_UNIT 3000
+#        define RETRY_INTERVAL 100000
+         for (;;) {
+             int ack_count;
+
+             sem_getvalue(&GC_suspend_ack_sem, &ack_count);
+             if (ack_count == n_live_threads) break;
+             if (wait_usecs > RETRY_INTERVAL) {
+                 int newly_sent = GC_suspend_all();
+
+#                 ifdef CONDPRINT
+                   if (GC_print_stats) {
+                     GC_printf1("Resent %ld signals after timeout\n",
+                                newly_sent);
+                   }
+#                 endif
+                 sem_getvalue(&GC_suspend_ack_sem, &ack_count);
+                 if (newly_sent < n_live_threads - ack_count) {
+                     WARN("Lost some threads during GC_stop_world?!\n",0);
+                     n_live_threads = ack_count + newly_sent;
+                 }
+                 wait_usecs = 0;
+             }
+             usleep(WAIT_UNIT);
+             wait_usecs += WAIT_UNIT;
+         }
+      }
+    for (i = 0; i < n_live_threads; i++) {
+         if (0 != (code = sem_wait(&GC_suspend_ack_sem))) {
+             GC_err_printf1("Sem_wait returned %ld\n", (unsigned long)code);
+             ABORT("sem_wait for handler failed");
+         }
+    }
+#   ifdef PARALLEL_MARK
+      GC_release_mark_lock();
+#   endif
+    #if DEBUG_THREADS
+      GC_printf1("World stopped from 0x%lx\n", pthread_self());
+    #endif
+    GC_stopping_thread = 0;  /* debugging only */
+}
+
+/* Caller holds allocation lock, and has held it continuously since    */
+/* the world stopped.                                                  */
+void GC_start_world()
+{
+    pthread_t my_thread = pthread_self();
+    register int i;
+    register GC_thread p;
+    register int n_live_threads = 0;
+    register int result;
+
+#   if DEBUG_THREADS
+      GC_printf0("World starting\n");
+#   endif
+
+    for (i = 0; i < THREAD_TABLE_SZ; i++) {
+      for (p = GC_threads[i]; p != 0; p = p -> next) {
+        if (p -> id != my_thread) {
+            if (p -> flags & FINISHED) continue;
+           if (p -> thread_blocked) continue;
+            n_live_threads++;
+           #if DEBUG_THREADS
+             GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
+           #endif
+        
+        result = pthread_kill(p -> id, SIG_THR_RESTART);
+           switch(result) {
+                case ESRCH:
+                    /* Not really there anymore.  Possible? */
+                    n_live_threads--;
+                    break;
+                case 0:
+                    break;
+                default:
+                    ABORT("pthread_kill failed");
+            }
+        }
+      }
+    }
+    #if DEBUG_THREADS
+      GC_printf0("World started\n");
+    #endif
+}
+
+void GC_stop_init() {
+    struct sigaction act;
+    
+    if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
+        ABORT("sem_init failed");
+
+    act.sa_flags = SA_RESTART;
+    if (sigfillset(&act.sa_mask) != 0) {
+       ABORT("sigfillset() failed");
+    }
+#   ifdef NO_SIGNALS
+      if (sigdelset(&act.sa_mask, SIGINT) != 0
+         || sigdelset(&act.sa_mask, SIGQUIT != 0)
+         || sigdelset(&act.sa_mask, SIGABRT != 0)
+         || sigdelset(&act.sa_mask, SIGTERM != 0)) {
+        ABORT("sigdelset() failed");
+      }
+#   endif
+
+    /* SIG_THR_RESTART is unmasked by the handler when necessary.      */
+    act.sa_handler = GC_suspend_handler;
+    if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
+       ABORT("Cannot set SIG_SUSPEND handler");
+    }
+
+    act.sa_handler = GC_restart_handler;
+    if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) {
+       ABORT("Cannot set SIG_THR_RESTART handler");
+    }
+
+    /* Check for GC_RETRY_SIGNALS.     */
+      if (0 != GETENV("GC_RETRY_SIGNALS")) {
+         GC_retry_signals = TRUE;
+      }
+      if (0 != GETENV("GC_NO_RETRY_SIGNALS")) {
+         GC_retry_signals = FALSE;
+      }
+#     ifdef CONDPRINT
+          if (GC_print_stats && GC_retry_signals) {
+              GC_printf0("Will retry suspend signal if necessary.\n");
+         }
+#     endif
+}
+
+#endif
similarity index 71%
rename from linux_threads.c
rename to pthread_support.c
index efb4c549a596189e39a8372c981b41eea4d0c540..de450da184009a26f6da7a2b8f364c1629638f72 100644 (file)
  /* DG/UX ix86 support <takis@xfree86.org> */
 /*
  * Linux_threads.c now also includes some code to support HPUX and
- * OSF1 (Compaq Tru64 Unix, really).  The OSF1 support is not yet
- * functional.  The OSF1 code is based on Eric Benson's
- * patch, though that was originally against hpux_irix_threads.  The code
- * here is completely untested.  With 0.0000001% probability, it might
- * actually work.
+ * OSF1 (Compaq Tru64 Unix, really).  The OSF1 support is based on Eric Benson's
+ * patch.
  *
  * Eric also suggested an alternate basis for a lock implementation in
  * his code:
  * + #  define GC_LOCK_TAKEN GC_allocate_lock
  */
 
-/* #define DEBUG_THREADS 1 */
+/*#define DEBUG_THREADS 1*/
+/*#define GC_ASSERTIONS*/
 
-/* ANSI C requires that a compilation unit contains something */
-
-# include "gc.h"
+# include "private/pthread_support.h"
 
 # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
-     && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
-
-# include "private/gc_priv.h"
+     && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \
+     && !defined(GC_AIX_THREADS)
 
 # if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
      && !defined(USE_HPUX_TLS)
 #   define USE_HPUX_TLS
 # endif
 
-# if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS)) \
-      && !defined(USE_PTHREAD_SPECIFIC)
+# if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
+      defined(GC_DARWIN_THREADS)) && !defined(USE_PTHREAD_SPECIFIC)
 #   define USE_PTHREAD_SPECIFIC
 # endif
 
 # include <unistd.h>
 # include <sys/mman.h>
 # include <sys/time.h>
-# include <semaphore.h>
-# include <signal.h>
 # include <sys/types.h>
 # include <sys/stat.h>
 # include <fcntl.h>
 
+#if defined(GC_DARWIN_THREADS)
+# include "private/darwin_semaphore.h"
+#else
+# include <semaphore.h>
+#endif /* !GC_DARWIN_THREADS */
+
+#if defined(GC_DARWIN_THREADS)
+# include <sys/sysctl.h>
+#endif /* GC_DARWIN_THREADS */
+
+
+
 #if defined(GC_DGUX386_THREADS)
 # include <sys/dg_sys_info.h>
 # include <sys/_int_psem.h>
 #     define REAL_FUNC(f) __d10_##f
 #   endif /* GC_DGUX386_THREADS */
 #   undef pthread_create
+#   if !defined(GC_DARWIN_THREADS)
 #   undef pthread_sigmask
+#   endif
 #   undef pthread_join
 #   undef pthread_detach
 #endif
 
-
 void GC_thr_init();
 
-#if DEBUG_THREADS
-
-#ifndef NSIG
-# if defined(MAXSIG)
-#  define NSIG (MAXSIG+1)
-# elif defined(_NSIG)
-#  define NSIG _NSIG
-# elif defined(__SIGRTMAX)
-#  define NSIG (__SIGRTMAX+1)
-# else
-  --> please fix it
-# endif
-#endif
-
-void GC_print_sig_mask()
-{
-    sigset_t blocked;
-    int i;
-
-    if (pthread_sigmask(SIG_BLOCK, NULL, &blocked) != 0)
-       ABORT("pthread_sigmask");
-    GC_printf0("Blocked: ");
-    for (i = 1; i < NSIG; i++) {
-        if (sigismember(&blocked, i)) { GC_printf1("%ld ",(long) i); }
-    }
-    GC_printf0("\n");
-}
-#endif
-
-word GC_stop_count;    /* Incremented at the beginning of GC_stop_world. */
-
-#ifdef GC_OSF1_THREADS
-  GC_bool GC_retry_signals = TRUE;
-#else
-  GC_bool GC_retry_signals = FALSE;
-#endif
-
-/* We use the allocation lock to protect thread-related data structures. */
-
-/* The set of all known threads.  We intercept thread creation and     */
-/* joins.                                                              */
-/* Protected by allocation/GC lock.                                    */
-/* Some of this should be declared volatile, but that's inconsistent   */
-/* with some library routine declarations.                             */
-typedef struct GC_Thread_Rep {
-    struct GC_Thread_Rep * next;  /* More recently allocated threads   */
-                                 /* with a given pthread id come       */
-                                 /* first.  (All but the first are     */
-                                 /* guaranteed to be dead, but we may  */
-                                 /* not yet have registered the join.) */
-    pthread_t id;
-    short flags;
-#      define FINISHED 1       /* Thread has exited.   */
-#      define DETACHED 2       /* Thread is intended to be detached.   */
-#      define MAIN_THREAD 4    /* True for the original thread only.   */
-    short thread_blocked;      /* Protected by GC lock.                */
-                               /* Treated as a boolean value.  If set, */
-                               /* thread will acquire GC lock before   */
-                               /* doing any pointer manipulations, and */
-                               /* has set its sp value.  Thus it does  */
-                               /* not need to be sent a signal to stop */
-                               /* it.                                  */
-    ptr_t stack_end;           /* Cold end of the stack.               */
-    ptr_t stack_ptr;           /* Valid only when stopped.             */
-#   ifdef IA64
-       ptr_t backing_store_end;
-       ptr_t backing_store_ptr;
-#   endif
-    int        signal;
-    void * status;             /* The value returned from the thread.  */
-                               /* Used only to avoid premature         */
-                               /* reclamation of any data it might     */
-                               /* reference.                           */
-    word last_stop_count;      /* GC_last_stop_count value when thread */
-                               /* last successfully handled a suspend  */
-                               /* signal.                              */
-#   ifdef THREAD_LOCAL_ALLOC
-#      if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
-#          define GRANULARITY 16
-#          define NFREELISTS 49
-#      else
-#          define GRANULARITY 8
-#          define NFREELISTS 65
-#      endif
-       /* The ith free list corresponds to size i*GRANULARITY */
-#      define INDEX_FROM_BYTES(n) ((ADD_SLOP(n) + GRANULARITY - 1)/GRANULARITY)
-#      define BYTES_FROM_INDEX(i) ((i) * GRANULARITY - EXTRA_BYTES)
-#      define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= \
-                                   (NFREELISTS-1)*GRANULARITY)
-       ptr_t ptrfree_freelists[NFREELISTS];
-       ptr_t normal_freelists[NFREELISTS];
-#      ifdef GC_GCJ_SUPPORT
-         ptr_t gcj_freelists[NFREELISTS];
-#      endif
-               /* Free lists contain either a pointer or a small count */
-               /* reflecting the number of granules allocated at that  */
-               /* size.                                                */
-               /* 0 ==> thread-local allocation in use, free list      */
-               /*       empty.                                         */
-               /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
-               /*       too few objects of this size have been         */
-               /*       allocated by this thread.                      */
-               /* >= HBLKSIZE  => pointer to nonempty free list.       */
-               /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to      */
-               /*    local alloc, equivalent to 0.                     */
-#      define DIRECT_GRANULES (HBLKSIZE/GRANULARITY)
-               /* Don't use local free lists for up to this much       */
-               /* allocation.                                          */
-#   endif
-} * GC_thread;
-
-GC_thread GC_lookup_thread(pthread_t id);
-
 static GC_bool parallel_initialized = FALSE;
 
 void GC_init_parallel();
@@ -362,7 +255,9 @@ GC_PTR GC_local_malloc(size_t bytes)
        int index = INDEX_FROM_BYTES(bytes);
        ptr_t * my_fl;
        ptr_t my_entry;
+#      if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
        GC_key_t k = GC_thread_key;
+#      endif
        void * tsd;
 
 #      if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
@@ -409,13 +304,14 @@ GC_PTR GC_local_malloc_atomic(size_t bytes)
        ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
                        -> ptrfree_freelists + index;
        ptr_t my_entry = *my_fl;
+    
        if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
            GC_PTR result = (GC_PTR)my_entry;
            *my_fl = obj_link(my_entry);
            return result;
        } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
            *my_fl = my_entry + index + 1;
-            return GC_malloc_atomic(bytes);
+        return GC_malloc_atomic(bytes);
        } else {
            GC_generic_malloc_many(BYTES_FROM_INDEX(index), PTRFREE, my_fl);
            /* *my_fl is updated while the collector is excluded;       */
@@ -487,32 +383,6 @@ GC_PTR GC_local_gcj_malloc(size_t bytes,
 
 # endif /* !THREAD_LOCAL_ALLOC */
 
-/*
- * We use signals to stop threads during GC.
- * 
- * Suspended threads wait in signal handler for SIG_THR_RESTART.
- * That's more portable than semaphores or condition variables.
- * (We do use sem_post from a signal handler, but that should be portable.)
- *
- * The thread suspension signal SIG_SUSPEND is now defined in gc_priv.h.
- * Note that we can't just stop a thread; we need it to save its stack
- * pointer(s) and acknowledge.
- */
-
-#ifndef SIG_THR_RESTART
-#  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
-#    ifdef _SIGRTMIN
-#      define SIG_THR_RESTART _SIGRTMIN + 5
-#    else
-#      define SIG_THR_RESTART SIGRTMIN + 5
-#    endif
-#  else
-#   define SIG_THR_RESTART SIGXCPU
-#  endif
-#endif
-
-sem_t GC_suspend_ack_sem;
-
 #if 0
 /*
 To make sure that we're using LinuxThreads and not some other thread
@@ -527,10 +397,6 @@ actually work for something else.
 void (*dummy_var_to_force_linux_threads)() = pthread_kill_other_threads_np;
 #endif /* 0 */
 
-#if defined(SPARC) || defined(IA64)
-  extern word GC_save_regs_in_stack();
-#endif
-
 long GC_nprocs = 1;    /* Number of processors.  We may not have       */
                        /* access to all of them, but this is as good   */
                        /* a guess as any ...                           */
@@ -627,112 +493,6 @@ static __inline__ void start_mark_threads()
 
 #endif /* !PARALLEL_MARK */
 
-void GC_suspend_handler(int sig)
-{
-    int dummy;
-    pthread_t my_thread = pthread_self();
-    GC_thread me;
-    sigset_t all_sigs;
-    sigset_t old_sigs;
-    int i;
-    sigset_t mask;
-#   ifdef PARALLEL_MARK
-       word my_mark_no = GC_mark_no;
-       /* Marker can't proceed until we acknowledge.  Thus this is     */
-       /* guaranteed to be the mark_no correspending to our            */
-       /* suspension, i.e. the marker can't have incremented it yet.   */
-#   endif
-    word my_stop_count = GC_stop_count;
-
-    if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
-
-#if DEBUG_THREADS
-    GC_printf1("Suspending 0x%lx\n", my_thread);
-#endif
-
-    me = GC_lookup_thread(my_thread);
-    /* The lookup here is safe, since I'm doing this on behalf  */
-    /* of a thread which holds the allocation lock in order    */
-    /* to stop the world.  Thus concurrent modification of the */
-    /* data structure is impossible.                           */
-    if (me -> last_stop_count == my_stop_count) {
-       /* Duplicate signal.  OK if we are retrying.    */
-       if (!GC_retry_signals) {
-           WARN("Duplicate suspend signal in thread %lx\n",
-                pthread_self());
-       }
-       return;
-    }
-#   ifdef SPARC
-       me -> stack_ptr = (ptr_t)GC_save_regs_in_stack();
-#   else
-       me -> stack_ptr = (ptr_t)(&dummy);
-#   endif
-#   ifdef IA64
-       me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack();
-#   endif
-
-    /* Tell the thread that wants to stop the world that this   */
-    /* thread has been stopped.  Note that sem_post() is       */
-    /* the only async-signal-safe primitive in LinuxThreads.    */
-    sem_post(&GC_suspend_ack_sem);
-    me -> last_stop_count = my_stop_count;
-
-    /* Wait until that thread tells us to restart by sending    */
-    /* this thread a SIG_THR_RESTART signal.                   */
-    /* SIG_THR_RESTART should be masked at this point.  Thus there     */
-    /* is no race.                                             */
-    if (sigfillset(&mask) != 0) ABORT("sigfillset() failed");
-    if (sigdelset(&mask, SIG_THR_RESTART) != 0) ABORT("sigdelset() failed");
-#   ifdef NO_SIGNALS
-      if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
-      if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
-      if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
-      if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
-#   endif
-    do {
-           me->signal = 0;
-           sigsuspend(&mask);             /* Wait for signal */
-    } while (me->signal != SIG_THR_RESTART);
-    /* If the RESTART signal gets lost, we can still lose.  That should be  */
-    /* less likely than losing the SUSPEND signal, since we don't do much   */
-    /* between the sem_post and sigsuspend.                                */
-    /* We'd need more handshaking to work around that, since we don't want  */
-    /* to accidentally leave a RESTART signal pending, thus causing us to   */
-    /* continue prematurely in a future round.                             */ 
-
-#if DEBUG_THREADS
-    GC_printf1("Continuing 0x%lx\n", my_thread);
-#endif
-}
-
-void GC_restart_handler(int sig)
-{
-    GC_thread me;
-
-    if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
-
-    /* Let the GC_suspend_handler() know that we got a SIG_THR_RESTART. */
-    /* The lookup here is safe, since I'm doing this on behalf  */
-    /* of a thread which holds the allocation lock in order    */
-    /* to stop the world.  Thus concurrent modification of the */
-    /* data structure is impossible.                           */
-    me = GC_lookup_thread(pthread_self());
-    me->signal = SIG_THR_RESTART;
-
-    /*
-    ** Note: even if we didn't do anything useful here,
-    ** it would still be necessary to have a signal handler,
-    ** rather than ignoring the signals, otherwise
-    ** the signals will not be delivered at all, and
-    ** will thus not interrupt the sigsuspend() above.
-    */
-
-#if DEBUG_THREADS
-    GC_printf1("In GC_restart_handler for 0x%lx\n", pthread_self());
-#endif
-}
-
 /* Defining INSTALL_LOOPING_SEGV_HANDLER causes SIGSEGV and SIGBUS to  */
 /* result in an infinite loop in a signal handler.  This can be very   */
 /* useful for debugging, since (as of RH7) gdb still seems to have     */
@@ -748,12 +508,15 @@ void GC_looping_handler(int sig)
 
 GC_bool GC_thr_initialized = FALSE;
 
-# define THREAD_TABLE_SZ 128   /* Must be power of 2   */
 volatile GC_thread GC_threads[THREAD_TABLE_SZ];
 
 void GC_push_thread_structures GC_PROTO((void))
 {
     GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
+#   if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
+      GC_push_all((ptr_t)(&GC_thread_key),
+         (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key));
+#   endif
 }
 
 #ifdef THREAD_LOCAL_ALLOC
@@ -899,218 +662,6 @@ void GC_remove_all_threads_but_me(void)
 }
 #endif /* HANDLE_FORK */
 
-/* There seems to be a very rare thread stopping problem.  To help us  */
-/* debug that, we save the ids of the stopping thread. */
-pthread_t GC_stopping_thread;
-int GC_stopping_pid;
-
-/* We hold the allocation lock.  Suspend all threads that might        */
-/* still be running.  Return the number of suspend signals that        */
-/* were sent.                                                  */
-int GC_suspend_all()
-{
-    int n_live_threads = 0;
-    int i;
-    GC_thread p;
-    int result;
-    pthread_t my_thread = pthread_self();
-
-    GC_stopping_thread = my_thread;    /* debugging only.      */
-    GC_stopping_pid = getpid();                /* debugging only.      */
-    for (i = 0; i < THREAD_TABLE_SZ; i++) {
-      for (p = GC_threads[i]; p != 0; p = p -> next) {
-        if (p -> id != my_thread) {
-            if (p -> flags & FINISHED) continue;
-           if (p -> last_stop_count == GC_stop_count) continue;
-           if (p -> thread_blocked) /* Will wait */ continue;
-            n_live_threads++;
-           #if DEBUG_THREADS
-             GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
-           #endif
-            result = pthread_kill(p -> id, SIG_SUSPEND);
-           switch(result) {
-                case ESRCH:
-                    /* Not really there anymore.  Possible? */
-                    n_live_threads--;
-                    break;
-                case 0:
-                    break;
-                default:
-                    ABORT("pthread_kill failed");
-            }
-        }
-      }
-    }
-    return n_live_threads;
-}
-
-/* Caller holds allocation lock.       */
-void GC_stop_world()
-{
-    register int i;
-    register int n_live_threads;
-
-    /* Make sure all free list construction has stopped before we start. */
-    /* No new construction can start, since free list construction is  */
-    /* required to acquire and release the GC lock before it starts,   */
-    /* and we have the lock.                                           */
-#   ifdef PARALLEL_MARK
-      GC_acquire_mark_lock();
-      GC_ASSERT(GC_fl_builder_count == 0);
-      /* We should have previously waited for it to become zero. */
-#   endif /* PARALLEL_MARK */
-    ++GC_stop_count;
-    n_live_threads = GC_suspend_all();
-    if (GC_retry_signals) {
-       unsigned long wait_usecs = 0;  /* Total wait since retry.       */
-#      define WAIT_UNIT 3000
-#      define RETRY_INTERVAL 100000
-       for (;;) {
-           int ack_count;
-
-           sem_getvalue(&GC_suspend_ack_sem, &ack_count);
-           if (ack_count == n_live_threads) break;
-           if (wait_usecs > RETRY_INTERVAL) {
-               int newly_sent = GC_suspend_all();
-
-#               ifdef CONDPRINT
-                  if (GC_print_stats) {
-                   GC_printf1("Resent %ld signals after timeout\n",
-                              newly_sent);
-                 }
-#               endif
-               sem_getvalue(&GC_suspend_ack_sem, &ack_count);
-               if (newly_sent < n_live_threads - ack_count) {
-                   WARN("Lost some threads during GC_stop_world?!\n",0);
-                   n_live_threads = ack_count + newly_sent;
-               }
-               wait_usecs = 0;
-           }
-           usleep(WAIT_UNIT);
-           wait_usecs += WAIT_UNIT;
-       }
-    }
-    for (i = 0; i < n_live_threads; i++) {
-       if (0 != sem_wait(&GC_suspend_ack_sem))
-           ABORT("sem_wait in handler failed");
-    }
-#   ifdef PARALLEL_MARK
-      GC_release_mark_lock();
-#   endif
-    #if DEBUG_THREADS
-      GC_printf1("World stopped from 0x%lx\n", pthread_self());
-    #endif
-    GC_stopping_thread = 0;  /* debugging only */
-}
-
-/* Caller holds allocation lock, and has held it continuously since    */
-/* the world stopped.                                                  */
-void GC_start_world()
-{
-    pthread_t my_thread = pthread_self();
-    register int i;
-    register GC_thread p;
-    register int n_live_threads = 0;
-    register int result;
-    
-#   if DEBUG_THREADS
-      GC_printf0("World starting\n");
-#   endif
-
-    for (i = 0; i < THREAD_TABLE_SZ; i++) {
-      for (p = GC_threads[i]; p != 0; p = p -> next) {
-        if (p -> id != my_thread) {
-            if (p -> flags & FINISHED) continue;
-           if (p -> thread_blocked) continue;
-            n_live_threads++;
-           #if DEBUG_THREADS
-             GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
-           #endif
-            result = pthread_kill(p -> id, SIG_THR_RESTART);
-           switch(result) {
-                case ESRCH:
-                    /* Not really there anymore.  Possible? */
-                    n_live_threads--;
-                    break;
-                case 0:
-                    break;
-                default:
-                    ABORT("pthread_kill failed");
-            }
-        }
-      }
-    }
-    #if DEBUG_THREADS
-      GC_printf0("World started\n");
-    #endif
-}
-
-# ifdef IA64
-#   define IF_IA64(x) x
-# else
-#   define IF_IA64(x)
-# endif
-/* We hold allocation lock.  Should do exactly the right thing if the  */
-/* world is stopped.  Should not fail if it isn't.                     */
-void GC_push_all_stacks()
-{
-    int i;
-    GC_thread p;
-    ptr_t sp = GC_approx_sp();
-    ptr_t lo, hi;
-    /* On IA64, we also need to scan the register backing store. */
-    IF_IA64(ptr_t bs_lo; ptr_t bs_hi;)
-    pthread_t me = pthread_self();
-    
-    if (!GC_thr_initialized) GC_thr_init();
-    #if DEBUG_THREADS
-        GC_printf1("Pushing stacks from thread 0x%lx\n", (unsigned long) me);
-    #endif
-    for (i = 0; i < THREAD_TABLE_SZ; i++) {
-      for (p = GC_threads[i]; p != 0; p = p -> next) {
-        if (p -> flags & FINISHED) continue;
-        if (pthread_equal(p -> id, me)) {
-#          ifdef SPARC
-               lo = (ptr_t)GC_save_regs_in_stack();
-#          else
-               lo = GC_approx_sp();
-#           endif
-           IF_IA64(bs_hi = (ptr_t)GC_save_regs_in_stack();)
-       } else {
-           lo = p -> stack_ptr;
-           IF_IA64(bs_hi = p -> backing_store_ptr;)
-       }
-        if ((p -> flags & MAIN_THREAD) == 0) {
-           hi = p -> stack_end;
-           IF_IA64(bs_lo = p -> backing_store_end);
-        } else {
-            /* The original stack. */
-            hi = GC_stackbottom;
-           IF_IA64(bs_lo = BACKING_STORE_BASE;)
-        }
-        #if DEBUG_THREADS
-            GC_printf3("Stack for thread 0x%lx = [%lx,%lx)\n",
-               (unsigned long) p -> id,
-               (unsigned long) lo, (unsigned long) hi);
-        #endif
-       if (0 == lo) ABORT("GC_push_all_stacks: sp not set!\n");
-#       ifdef STACK_GROWS_UP
-         /* We got them backwards! */
-          GC_push_all_stack(hi, lo);
-#       else
-          GC_push_all_stack(lo, hi);
-#      endif
-#      ifdef IA64
-          if (pthread_equal(p -> id, me)) {
-           GC_push_all_eager(bs_lo, bs_hi);
-         } else {
-           GC_push_all_stack(bs_lo, bs_hi);
-         }
-#      endif
-      }
-    }
-}
-
 #ifdef USE_PROC_FOR_LIBRARIES
 int GC_segment_is_thread_stack(ptr_t lo, ptr_t hi)
 {
@@ -1145,14 +696,11 @@ int GC_get_nprocs()
     /* appears to be buggy in many cases.                              */
     /* We look for lines "cpu<n>" in /proc/stat.                       */
 #   define STAT_BUF_SIZE 4096
-#   if defined(GC_USE_LD_WRAP)
-#      define STAT_READ __real_read
-#   else
-#      define STAT_READ read
-#   endif    
+#   define STAT_READ read
+       /* If read is wrapped, this may need to be redefined to call    */
+       /* the real one.                                                */
     char stat_buf[STAT_BUF_SIZE];
     int f;
-    char c;
     word result = 1;
        /* Some old kernels only have a single "cpu nnnn ..."   */
        /* entry in /proc/stat.  We identify those as           */
@@ -1181,6 +729,7 @@ int GC_get_nprocs()
 /* If wait_for_all is true, then we exit with the GC lock held and no  */
 /* collection in progress; otherwise we just wait for the current GC   */
 /* to finish.                                                          */
+extern GC_bool GC_collection_in_progress();
 void GC_wait_for_gc_completion(GC_bool wait_for_all)
 {
     if (GC_incremental && GC_collection_in_progress()) {
@@ -1284,39 +833,14 @@ int GC_get_nprocs()
 /* We hold the allocation lock.        */
 void GC_thr_init()
 {
-    int dummy;
+#      ifndef GC_DARWIN_THREADS
+        int dummy;
+#      endif
     GC_thread t;
-    struct sigaction act;
 
     if (GC_thr_initialized) return;
     GC_thr_initialized = TRUE;
-
-    if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
-       ABORT("sem_init failed");
-
-    act.sa_flags = SA_RESTART;
-    if (sigfillset(&act.sa_mask) != 0) {
-       ABORT("sigfillset() failed");
-    }
-#   ifdef NO_SIGNALS
-      if (sigdelset(&act.sa_mask, SIGINT) != 0
-         || sigdelset(&act.sa_mask, SIGQUIT != 0)
-         || sigdelset(&act.sa_mask, SIGABRT != 0)
-         || sigdelset(&act.sa_mask, SIGTERM != 0)) {
-        ABORT("sigdelset() failed");
-      }
-#   endif
-
-    /* SIG_THR_RESTART is unmasked by the handler when necessary.      */
-    act.sa_handler = GC_suspend_handler;
-    if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
-       ABORT("Cannot set SIG_SUSPEND handler");
-    }
-
-    act.sa_handler = GC_restart_handler;
-    if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) {
-       ABORT("Cannot set SIG_THR_RESTART handler");
-    }
+    
 #   ifdef HANDLE_FORK
       /* Prepare for a possible fork.  */
         pthread_atfork(GC_fork_prepare_proc, GC_fork_parent_proc,
@@ -1324,21 +848,14 @@ void GC_thr_init()
 #   endif /* HANDLE_FORK */
     /* Add the initial thread, so we can stop it.      */
       t = GC_new_thread(pthread_self());
-      t -> stack_ptr = (ptr_t)(&dummy);
+#     ifdef GC_DARWIN_THREADS
+         t -> stop_info.mach_thread = mach_thread_self();
+#     else
+         t -> stop_info.stack_ptr = (ptr_t)(&dummy);
+#     endif
       t -> flags = DETACHED | MAIN_THREAD;
 
-    /* Check for GC_RETRY_SIGNALS.     */
-      if (0 != GETENV("GC_RETRY_SIGNALS")) {
-         GC_retry_signals = TRUE;
-      }
-      if (0 != GETENV("GC_NO_RETRY_SIGNALS")) {
-         GC_retry_signals = FALSE;
-      }
-#     ifdef CONDPRINT
-          if (GC_print_stats) {
-              GC_printf0("Will retry suspend signal if necessary.\n");
-         }
-#     endif
+    GC_stop_init();
 
     /* Set GC_nprocs.  */
       {
@@ -1357,6 +874,12 @@ void GC_thr_init()
 #       if defined(GC_FREEBSD_THREADS)
           GC_nprocs = 1;
 #       endif
+#       if defined(GC_DARWIN_THREADS)
+         int ncpus = 1;
+         size_t len = sizeof(ncpus);
+         sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
+         GC_nprocs = ncpus;
+#       endif
 #      if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)
           GC_nprocs = GC_get_nprocs();
 #      endif
@@ -1411,7 +934,8 @@ void GC_init_parallel()
 {
     if (parallel_initialized) return;
     parallel_initialized = TRUE;
-       /* GC_init() calls us back, so set flag first.  */
+
+    /* GC_init() calls us back, so set flag first.     */
     if (!GC_is_initialized) GC_init();
     /* If we are using a parallel marker, start the helper threads.  */
 #     ifdef PARALLEL_MARK
@@ -1426,6 +950,7 @@ void GC_init_parallel()
 }
 
 
+#if !defined(GC_DARWIN_THREADS)
 int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
 {
     sigset_t fudged_set;
@@ -1437,6 +962,7 @@ int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
     }
     return(REAL_FUNC(pthread_sigmask)(how, set, oset));
 }
+#endif /* !GC_DARWIN_THREADS */
 
 /* Wrappers for functions that are likely to block for an appreciable  */
 /* length of time.  Must be called in pairs, if at all.                        */
@@ -1450,25 +976,29 @@ void GC_start_blocking(void) {
     me = GC_lookup_thread(pthread_self());
     GC_ASSERT(!(me -> thread_blocked));
 #   ifdef SPARC
-       me -> stack_ptr = (ptr_t)GC_save_regs_in_stack();
+       me -> stop_info.stack_ptr = (ptr_t)GC_save_regs_in_stack();
 #   else
-       me -> stack_ptr = (ptr_t)GC_approx_sp();
+#   ifndef GC_DARWIN_THREADS
+       me -> stop_info.stack_ptr = (ptr_t)GC_approx_sp();
+#   endif
 #   endif
 #   ifdef IA64
        me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack() + SP_SLOP;
 #   endif
     /* Add some slop to the stack pointer, since the wrapped call may  */
     /* end up pushing more callee-save registers.                      */
+#   ifndef GC_DARWIN_THREADS
 #   ifdef STACK_GROWS_UP
-       me -> stack_ptr += SP_SLOP;
+       me -> stop_info.stack_ptr += SP_SLOP;
 #   else
-       me -> stack_ptr -= SP_SLOP;
+       me -> stop_info.stack_ptr -= SP_SLOP;
+#   endif
 #   endif
     me -> thread_blocked = TRUE;
     UNLOCK();
 }
 
-GC_end_blocking(void) {
+void GC_end_blocking(void) {
     GC_thread me;
     LOCK();   /* This will block if the world is stopped.      */
     me = GC_lookup_thread(pthread_self());
@@ -1596,8 +1126,12 @@ void * GC_start_routine(void * arg)
 #   endif
     LOCK();
     me = GC_new_thread(my_pthread);
+#ifdef GC_DARWIN_THREADS
+    me -> stop_info.mach_thread = mach_thread_self();
+#else
+    me -> stop_info.stack_ptr = 0;
+#endif
     me -> flags = si -> flags;
-    me -> stack_ptr = 0;
     /* me -> stack_end = GC_linux_stack_base(); -- currently (11/99)   */
     /* doesn't work because the stack base in /proc/self/stat is the   */
     /* one for the main thread.  There is a strong argument that that's        */
@@ -1605,12 +1139,14 @@ void * GC_start_routine(void * arg)
 #   ifdef STACK_GROWS_DOWN
       me -> stack_end = (ptr_t)(((word)(&dummy) + (GC_page_size - 1))
                                & ~(GC_page_size - 1));
-      me -> stack_ptr = me -> stack_end - 0x10;
+#        ifndef GC_DARWIN_THREADS
+        me -> stop_info.stack_ptr = me -> stack_end - 0x10;
+#        endif
        /* Needs to be plausible, since an asynchronous stack mark      */
        /* should not crash.                                            */
 #   else
       me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1));
-      me -> stack_ptr = me -> stack_end + 0x10;
+      me -> stop_info.stack_ptr = me -> stack_end + 0x10;
 #   endif
     /* This is dubious, since we may be more than a page into the stack, */
     /* and hence skip some of it, though it's not clear that matters.   */
@@ -1639,7 +1175,6 @@ void * GC_start_routine(void * arg)
         GC_printf1("Finishing thread 0x%x\n", pthread_self());
 #endif
     me -> status = result;
-    me -> flags |= FINISHED;
     pthread_cleanup_pop(1);
     /* Cleanup acquires lock, ensuring that we can't exit              */
     /* while a collection that thinks we're alive is trying to stop     */
@@ -1653,8 +1188,6 @@ WRAP_FUNC(pthread_create)(pthread_t *new_thread,
                   void *(*start_routine)(void *), void *arg)
 {
     int result;
-    GC_thread t;
-    pthread_t my_new_thread;
     int detachstate;
     word my_flags = 0;
     struct start_info * si; 
@@ -1676,6 +1209,22 @@ WRAP_FUNC(pthread_create)(pthread_t *new_thread,
     si -> arg = arg;
     LOCK();
     if (!GC_thr_initialized) GC_thr_init();
+#   ifdef GC_ASSERTIONS
+      {
+       int stack_size;
+       if (NULL == attr) {
+          pthread_attr_t my_attr;
+          pthread_attr_init(&my_attr);
+          pthread_attr_getstacksize(&my_attr, &stack_size);
+       } else {
+          pthread_attr_getstacksize(attr, &stack_size);
+       }
+       GC_ASSERT(stack_size >= (8*HBLKSIZE*sizeof(word)));
+       /* Our threads may need to do some work for the GC.     */
+       /* Ridiculously small threads won't work, and they      */
+       /* probably wouldn't work anyway.                       */
+      }
+#   endif
     if (NULL == attr) {
        detachstate = PTHREAD_CREATE_JOINABLE;
     } else { 
@@ -1690,6 +1239,7 @@ WRAP_FUNC(pthread_create)(pthread_t *new_thread,
 #   endif
 
     result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, si);
+
 #   ifdef DEBUG_THREADS
         GC_printf1("Started thread 0x%X\n", *new_thread);
 #   endif
@@ -1697,10 +1247,10 @@ WRAP_FUNC(pthread_create)(pthread_t *new_thread,
     /* This also ensures that we hold onto si until the child is done  */
     /* with it.  Thus it doesn't matter whether it is otherwise                */
     /* visible to the collector.                                       */
-        while (0 != sem_wait(&(si -> registered))) {
-           if (EINTR != errno) ABORT("sem_wait failed");
-       }
-        sem_destroy(&(si -> registered));
+    while (0 != sem_wait(&(si -> registered))) {
+        if (EINTR != errno) ABORT("sem_wait failed");
+    }
+    sem_destroy(&(si -> registered));
        LOCK();
        GC_INTERNAL_FREE(si);
        UNLOCK();
@@ -1742,7 +1292,9 @@ WRAP_FUNC(pthread_create)(pthread_t *new_thread,
 void GC_pause()
 {
     int i;
-    volatile word dummy = 0;
+#      ifndef __GNUC__
+        volatile word dummy = 0;
+#      endif
 
     for (i = 0; i < 10; ++i) { 
 #     ifdef __GNUC__
@@ -1781,6 +1333,7 @@ VOLATILE GC_bool GC_collecting = 0;
 
 void GC_generic_lock(pthread_mutex_t * lock)
 {
+#ifndef NO_PTHREAD_TRYLOCK
     unsigned pause_length = 1;
     unsigned i;
     
@@ -1798,6 +1351,7 @@ void GC_generic_lock(pthread_mutex_t * lock)
                ABORT("Unexpected error from pthread_mutex_trylock");
         }
     }
+#endif /* !NO_PTHREAD_TRYLOCK */
     pthread_mutex_lock(lock);
 }
 
@@ -1875,14 +1429,17 @@ yield:
 }
 
 #else  /* !USE_SPINLOCK */
-
 void GC_lock()
 {
+#ifndef NO_PTHREAD_TRYLOCK
     if (1 == GC_nprocs || GC_collecting) {
        pthread_mutex_lock(&GC_allocate_ml);
     } else {
         GC_generic_lock(&GC_allocate_ml);
     }
+#else  /* !NO_PTHREAD_TRYLOCK */
+    pthread_mutex_lock(&GC_allocate_ml);
+#endif /* !NO_PTHREAD_TRYLOCK */
 }
 
 #endif /* !USE_SPINLOCK */
index af49d5f5b791d378de9a29fc18f0c53acad6b14d..d83d730d3433f5f29b2da36e1c97013869b92394 100644 (file)
@@ -79,7 +79,7 @@ void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR, GC_PTR))
        return(p);
     }
     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
-    if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
+    if (sz > MAXOBJBYTES) {
       base = (ptr_t)HBLKPTR(p);
       limit = base + sz;
       if ((ptr_t)p >= limit) {
@@ -165,7 +165,7 @@ void (*GC_is_valid_displacement_print_proc) GC_PROTO((GC_PTR)) =
     pdispl = HBLKDISPL(p);
     map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
     if (map_entry == OBJ_INVALID
-       || sz > MAXOBJSZ && (ptr_t)p >= (ptr_t)h + sz) {
+       || sz > MAXOBJBYTES && (ptr_t)p >= (ptr_t)h + sz) {
        goto fail;
     }
     return(p);
index 93c7b9925429c9ab3a8e4bdada8fcd9dc47aa5f3..323d420fa40accbcac558207a8468ed13939d754 100644 (file)
--- a/reclaim.c
+++ b/reclaim.c
@@ -904,7 +904,7 @@ void GC_print_block_list()
  * Clear *flp.
  * This must be done before dropping a list of free gcj-style objects,
  * since may otherwise end up with dangling "descriptor" pointers.
- * It may help for other pointer-containg objects.
+ * It may help for other pointer-containing objects.
  */
 void GC_clear_fl_links(flp)
 ptr_t *flp;
index 51be6f5daa3d32c83be1989c1b97d556e081af79..cfe23c0efdee3df9fc1c69553cadd6a4bded798d 100644 (file)
 #   include <pthread.h>
 # endif
 
-# ifdef GC_WIN32_THREADS
-#   ifndef MSWINCE
-#     include <process.h>
-#     define GC_CreateThread(a,b,c,d,e,f) ((HANDLE) _beginthreadex(a,b,c,d,e,f))
-#   endif
+# if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
     static CRITICAL_SECTION incr_cs;
 # endif
 
+#ifdef __STDC__
+# include <stdarg.h>
+#endif
+
 
 /* Allocation Statistics */
 int stubborn_count = 0;
@@ -376,6 +376,9 @@ sexpr x, y;
 sexpr reverse(x)
 sexpr x;
 {
+#   ifdef TEST_WITH_SYSTEM_MALLOC
+      malloc(100000);
+#   endif
     return( reverse1(x, nil) );
 }
 
@@ -517,20 +520,13 @@ sexpr x;
     }
 }
 
-/* Try to force a to be strangely aligned */
-struct {
-  char dummy;
-  sexpr aa;
-} A;
-#define a A.aa
-
 /*
  * A tiny list reversal test to check thread creation.
  */
 #ifdef THREADS
 
 # if defined(GC_WIN32_THREADS) && !defined(CYGWIN32)
-    unsigned __stdcall tiny_reverse_test(void * arg)
+    DWORD  __stdcall tiny_reverse_test(void * arg)
 # else
     void * tiny_reverse_test(void * arg)
 # endif
@@ -565,7 +561,7 @@ struct {
 # elif defined(GC_WIN32_THREADS)
     void fork_a_thread()
     {
-       unsigned thread_id;
+       DWORD thread_id;
        HANDLE h;
        h = GC_CreateThread(NULL, 0, tiny_reverse_test, 0, 0, &thread_id);
         if (h == (HANDLE)NULL) {
@@ -594,6 +590,13 @@ struct {
 
 #endif 
 
+/* Try to force a to be strangely aligned */
+struct {
+  char dummy;
+  sexpr aa;
+} A;
+#define a A.aa
+
 /*
  * Repeatedly reverse lists built out of very different sized cons cells.
  * Check that we didn't lose anything.
@@ -714,6 +717,8 @@ void reverse_test()
     b = c = 0;
 }
 
+#undef a
+
 /*
  * The rest of this builds balanced binary trees, checks that they don't
  * disappear, and tests finalization.
@@ -758,6 +763,7 @@ VOLATILE int dropped_something = 0;
      FAIL;
   }
   finalized_count++;
+  t -> level = -1;     /* detect duplicate finalization immediately */
 # ifdef PCR
     PCR_ThCrSec_ExitSys();
 # endif
@@ -1165,6 +1171,25 @@ void fail_proc1(GC_PTR x)
     fail_count++;
 }   
 
+static void uniq(void *p, ...) {
+  va_list a;
+  void *q[100];
+  int n = 0, i, j;
+  q[n++] = p;
+  va_start(a,p);
+  for (;(q[n] = va_arg(a,void *));n++) ;
+  va_end(a);
+  for (i=0; i<n; i++)
+    for (j=0; j<i; j++)
+      if (q[i] == q[j]) {
+        GC_printf0(
+              "Apparently failed to mark form some function arguments.\n"
+              "Perhaps GC_push_regs was configured incorrectly?\n"
+        );
+       FAIL;
+      }
+}
+
 #endif /* __STDC__ */
 
 #ifdef THREADS
@@ -1277,6 +1302,21 @@ void run_one_test()
 #   ifdef GC_GCJ_SUPPORT
       GC_REGISTER_DISPLACEMENT(sizeof(struct fake_vtable *));
       GC_init_gcj_malloc(0, (void *)fake_gcj_mark_proc);
+#   endif
+    /* Make sure that fn arguments are visible to the collector.       */
+#   ifdef __STDC__
+      uniq(
+        GC_malloc(12), GC_malloc(12), GC_malloc(12),
+        (GC_gcollect(),GC_malloc(12)),
+        GC_malloc(12), GC_malloc(12), GC_malloc(12),
+       (GC_gcollect(),GC_malloc(12)),
+        GC_malloc(12), GC_malloc(12), GC_malloc(12),
+       (GC_gcollect(),GC_malloc(12)),
+        GC_malloc(12), GC_malloc(12), GC_malloc(12),
+       (GC_gcollect(),GC_malloc(12)),
+        GC_malloc(12), GC_malloc(12), GC_malloc(12),
+       (GC_gcollect(),GC_malloc(12)),
+        (void *)0);
 #   endif
     /* Repeated list reversal test. */
        reverse_test();
@@ -1446,6 +1486,10 @@ void SetMinimumStack(long minSize)
 #   endif
     n_tests = 0;
     
+#if defined(__APPLE__) && defined(__MACH__)
+       GC_INIT();
+#endif
+    
 #   if defined(DJGPP)
        /* No good way to determine stack base from library; do it */
        /* manually on this platform.                              */
@@ -1459,13 +1503,18 @@ void SetMinimumStack(long minSize)
 #   endif
     GC_INIT(); /* Only needed if gc is dynamic library.        */
     (void) GC_set_warn_proc(warn_proc);
-#   if (defined(MPROTECT_VDB) || defined(PROC_VDB)) && !defined(MAKE_BACK_GRAPH)
+#   if (defined(MPROTECT_VDB) || defined(PROC_VDB)) \
+          && !defined(MAKE_BACK_GRAPH)
       GC_enable_incremental();
       (void) GC_printf0("Switched to incremental mode\n");
 #     if defined(MPROTECT_VDB)
        (void)GC_printf0("Emulating dirty bits with mprotect/signals\n");
 #     else
+#       ifdef PROC_VDB
        (void)GC_printf0("Reading dirty bits from /proc\n");
+#       else
+    (void)GC_printf0("Using DEFAULT_VDB dirty bit implementation\n");
+#       endif
 #      endif
 #   endif
     run_one_test();
@@ -1499,7 +1548,7 @@ void SetMinimumStack(long minSize)
 
 #if defined(GC_WIN32_THREADS) && !defined(CYGWIN32)
 
-unsigned __stdcall thr_run_one_test(void *arg)
+DWORD __stdcall thr_run_one_test(void *arg)
 {
   run_one_test();
   return 0;
@@ -1531,7 +1580,7 @@ LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
   return ret;
 }
 
-unsigned __stdcall thr_window(void *arg)
+DWORD __stdcall thr_window(void *arg)
 {
   WNDCLASS win_class = {
     CS_NOCLOSE,
@@ -1593,10 +1642,11 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n)
 # ifdef MSWINCE
     HANDLE win_thr_h;
 # endif
-  unsigned thread_id;
+  DWORD thread_id;
 # if 0
     GC_enable_incremental();
 # endif
+  GC_init();
   InitializeCriticalSection(&incr_cs);
   (void) GC_set_warn_proc(warn_proc);
 # ifdef MSWINCE
@@ -1744,15 +1794,30 @@ main()
           (void)GC_printf0("pthread_default_stacksize_np failed.\n");
        }
 #   endif      /* GC_HPUX_THREADS */
+#      if defined(__APPLE__) && defined(__MACH__)
+               GC_INIT();
+#      endif
+
     pthread_attr_init(&attr);
-#   if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS)
+#   if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS) \
+       || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)
        pthread_attr_setstacksize(&attr, 1000000);
 #   endif
     n_tests = 0;
-#   if  defined(MPROTECT_VDB) && !defined(PARALLEL_MARK) &&!defined(REDIRECT_MALLOC) && !defined(MAKE_BACK_GRAPH)
+#   if (defined(MPROTECT_VDB)) \
+            && !defined(PARALLEL_MARK) &&!defined(REDIRECT_MALLOC) \
+            && !defined(MAKE_BACK_GRAPH)
        GC_enable_incremental();
         (void) GC_printf0("Switched to incremental mode\n");
-       (void) GC_printf0("Emulating dirty bits with mprotect/signals\n");
+#     if defined(MPROTECT_VDB)
+        (void)GC_printf0("Emulating dirty bits with mprotect/signals\n");
+#     else
+#       ifdef PROC_VDB
+            (void)GC_printf0("Reading dirty bits from /proc\n");
+#       else
+            (void)GC_printf0("Using DEFAULT_VDB dirty bit implementation\n");
+#       endif
+#     endif
 #   endif
     (void) GC_set_warn_proc(warn_proc);
     if ((code = pthread_key_create(&fl_key, 0)) != 0) {
index d6032b84b1f18c68aafcf738e148abe33fbfee13..7e50e8aa0fdd0ba20c7e4ce7e5c054ee328d0e74 100644 (file)
@@ -192,6 +192,8 @@ int APIENTRY WinMain(
 # endif
 #endif
 
+   GC_init();
+
 #  if defined(MACOS)                        // MacOS
     char* argv_[] = {"test_cpp", "10"};     //   doesn't
     argv = argv_;                           //     have a
@@ -214,8 +216,8 @@ int APIENTRY WinMain(
       x = 0;
 #   endif
     if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
-        GC_printf0( "usage: test_cpp number-of-iterations\n" );
-        exit( 1 );}
+        GC_printf0( "usage: test_cpp number-of-iterations\nAssuming 10 iters\n" );
+        n = 10;}
         
     for (iters = 1; iters <= n; iters++) {
         GC_printf1( "Starting iteration %d\n", iters );
index eaf6d9d74d66c3bf3bdd6676ea3678471e8290ec..247d3c652ec3a71c834879a1c2989de5778308cf 100644 (file)
@@ -4,13 +4,14 @@
 int main()
 {
 #   if defined(GC_USE_LD_WRAP)
-       printf("-Wl,--wrap -Wl,read -Wl,--wrap -Wl,dlopen "
+       printf("-Wl,--wrap -Wl,dlopen "
               "-Wl,--wrap -Wl,pthread_create -Wl,--wrap -Wl,pthread_join "
               "-Wl,--wrap -Wl,pthread_detach "
               "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n");
 #   endif
 #   if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \
-       || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS)
+       || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) \
+       || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)
         printf("-lpthread\n");
 #   endif
 #   if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
@@ -23,7 +24,7 @@ int main()
         printf("-lpthread\n");
 #   endif
 #   if defined(GC_OSF1_THREADS)
-       printf("-lpthread -lrt");
+       printf("-pthread -lrt"); /* DOB: must be -pthread, not -lpthread */
 #   endif
     /* You need GCC 3.0.3 to build this one!           */  
     /* DG/UX native gcc doesnt know what "-pthread" is */
index 07717001e9d1eb7327386ac4602e9d9860f07add..a081c9797c30248a95c58ee829b9913c76a51887 100644 (file)
@@ -437,6 +437,7 @@ void GC_init_explicit_typing()
     for (; bm != 0; bm >>= 1, current_p++) {
        if (bm & 1) {
            current = *current_p;
+           FIXUP_POINTER(current);
            if ((ptr_t)current >= least_ha && (ptr_t)current <= greatest_ha) {
                PUSH_CONTENTS((ptr_t)current, mark_stack_ptr,
                              mark_stack_limit, current_p, exit1);
@@ -674,9 +675,9 @@ DCL_LOCK_STATE;
         if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
             FASTUNLOCK();
             op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
-           if (0 == op) return(0);
+           if (0 == op) return 0;
 #          ifdef MERGE_SIZES
-               lw = GC_size_map[lb];   /* May have been uninitialized. */            
+               lw = GC_size_map[lb];   /* May have been uninitialized. */
 #          endif
         } else {
             *opp = obj_link(op);
@@ -720,7 +721,7 @@ DCL_LOCK_STATE;
             FASTUNLOCK();
             op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
 #          ifdef MERGE_SIZES
-               lw = GC_size_map[lb];   /* May have been uninitialized. */            
+               lw = GC_size_map[lb];   /* May have been uninitialized. */
 #          endif
         } else {
             *opp = obj_link(op);
index 554e2e2b2c1386879d93e92668dbb1a66e340f66..4c193a26dba373180e1f0ef4870d105a932b0982 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,11 +1,30 @@
-#define GC_VERSION_MAJOR 6
-#define GC_VERSION_MINOR 1
-#define GC_ALPHA_VERSION GC_NOT_ALPHA
+/* The version here should match that in configure/configure.in        */
+/* Eventually this one may become unnecessary.  For now we need        */
+/* it to keep the old-style build process working.             */
+#define GC_TMP_VERSION_MAJOR 6
+#define GC_TMP_VERSION_MINOR 2
+#define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA
 
+#ifndef GC_NOT_ALPHA
 #   define GC_NOT_ALPHA 0xff
+#endif
+
+#if defined(GC_VERSION_MAJOR)
+# if GC_TMP_VERSION_MAJOR != GC_VERSION_MAJOR || \
+     GC_TMP_VERSION_MINOR != GC_VERSION_MINOR || \
+     defined(GC_ALPHA_VERSION) != (GC_TMP_ALPHA_VERSION != GC_NOT_ALPHA) || \
+     defined(GC_ALPHA_VERSION) && GC_TMP_ALPHA_VERSION != GC_ALPHA_VERSION
+#   error Inconsistent version info.  Check version.h and configure.in.
+# endif
+#else
+# define GC_VERSION_MAJOR GC_TMP_VERSION_MAJOR
+# define GC_VERSION_MINOR GC_TMP_VERSION_MINOR
+# define GC_ALPHA_VERSION GC_TMP_ALPHA_VERSION
+#endif
+
 
 #ifndef GC_NO_VERSION_VAR
 
-unsigned GC_version = ((GC_VERSION_MAJOR << 16) | (GC_VERSION_MINOR << 8) | GC_ALPHA_VERSION);
+unsigned GC_version = ((GC_VERSION_MAJOR << 16) | (GC_VERSION_MINOR << 8) | GC_TMP_ALPHA_VERSION);
 
 #endif /* GC_NO_VERSION_VAR */ 
index 1f9ab94921789f097322d010d8a255f59c72d989..a2f65a5d797fd59cc987ca634438c1dcc199c5b0 100755 (executable)
@@ -1,6 +1,7 @@
 #if defined(GC_WIN32_THREADS) 
 
 #include "private/gc_priv.h"
+#include <windows.h>
 
 #ifdef CYGWIN32
 # include <errno.h>
 
 #endif
 
-
-#if 0
-#define STRICT
-#include <windows.h>
+#ifndef MAX_THREADS
+# define MAX_THREADS 64
 #endif
 
-#define MAX_THREADS 64
-
 struct thread_entry {
   LONG in_use;
   DWORD id;
@@ -58,7 +55,7 @@ void GC_push_thread_structures GC_PROTO((void))
     for (i = 0; i < MAX_THREADS; i++)
       if (thread_table[i].in_use) GC_push_all((ptr_t)&(thread_table[i].status),(ptr_t)(&(thread_table[i].status)+1));
   }
-#endif
+# endif
 }
 
 void GC_stop_world()
@@ -87,14 +84,15 @@ void GC_stop_world()
        DWORD exitCode; 
        if (GetExitCodeThread(thread_table[i].handle,&exitCode) &&
             exitCode != STILL_ACTIVE) {
-            thread_table[i].stack = 0; /* prevent stack from being pushed */
-#       ifndef CYGWIN32
-          /* this breaks pthread_join on Cygwin, which is guaranteed to only see user pthreads */
+          thread_table[i].stack = 0; /* prevent stack from being pushed */
+#         ifndef CYGWIN32
+            /* this breaks pthread_join on Cygwin, which is guaranteed to  */
+           /* only see user pthreads                                      */
            thread_table[i].in_use = FALSE;
            CloseHandle(thread_table[i].handle);
            BZERO((void *)(&thread_table[i].context), sizeof(CONTEXT));
-#endif
-           continue;
+#         endif
+         continue;
        }
        if (SuspendThread(thread_table[i].handle) == (DWORD)-1)
          ABORT("SuspendThread failed");
@@ -372,9 +370,13 @@ void GC_get_next_stack(char *start, char **lo, char **hi)
     if (*lo < start) *lo = start;
 }
 
-#if !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))
+#if !defined(CYGWIN32)
 
-HANDLE WINAPI GC_CreateThread(
+#if !defined(MSWINCE) && defined(GC_DLL)
+
+/* We register threads from DllMain */
+
+GC_API HANDLE GC_CreateThread(
     LPSECURITY_ATTRIBUTES lpThreadAttributes, 
     DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, 
     LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
@@ -383,7 +385,10 @@ HANDLE WINAPI GC_CreateThread(
                         lpParameter, dwCreationFlags, lpThreadId);
 }
 
-#else /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))  */
+#else /* defined(MSWINCE) || !defined(GC_DLL))  */
+
+/* We have no DllMain to take care of new threads.  Thus we    */
+/* must properly intercept thread creation.                    */
 
 typedef struct {
     HANDLE child_ready_h, parent_ready_h;
@@ -509,6 +514,8 @@ static DWORD WINAPI thread_start(LPVOID arg)
 }
 #endif /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))  */
 
+#endif /* !CYGWIN32 */
+
 #ifdef MSWINCE
 
 typedef struct {
@@ -564,10 +571,11 @@ DWORD WINAPI main_thread_start(LPVOID arg)
 
 LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info);
 
-/* threadAttach/threadDetach routines used by both CYGWIN and DLL implementation,
-   since both recieve explicit notification on thread creation/destruction
+/* threadAttach/threadDetach routines used by both CYGWIN and DLL
+ * implementation, since both recieve explicit notification on thread
+ * creation/destruction.
  */
-void threadAttach() {
+static void threadAttach() {
   int i;
   /* It appears to be unsafe to acquire a lock here, since this        */
   /* code is apparently not preeemptible on some systems.      */
@@ -616,7 +624,7 @@ void threadAttach() {
   while (GC_please_stop) Sleep(20);
 }
 
-void threadDetach(DWORD thread_id) {
+static void threadDetach(DWORD thread_id) {
   int i;
 
   LOCK();
@@ -782,7 +790,8 @@ void GC_thread_exit_proc(void *arg)
     int i;
 
 #   if DEBUG_CYGWIN_THREADS
-      GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",(int)pthread_self(),GetCurrentThreadId());
+      GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",
+                (int)pthread_self(),GetCurrentThreadId());
 #   endif
 
     LOCK();
@@ -805,13 +814,13 @@ int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) {
 int GC_pthread_detach(pthread_t thread) {
   return pthread_detach(thread);
 }
-#else
+#else /* !CYGWIN32 */
 
 /*
- * This isn't generally safe, since DllMain is not premptible.
- * If another thread holds the lock while this runs we're in trouble.
+ * We avoid acquiring locks here, since this doesn't seem to be preemptable.
  * Pontus Rydin suggests wrapping the thread start routine instead.
  */
+#ifdef GC_DLL
 BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
 {
   switch (reason) {
@@ -852,7 +861,8 @@ BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
   }
   return TRUE;
 }
-#endif /* CYGWIN32 */
+#endif /* GC_DLL */
+#endif /* !CYGWIN32 */
 
 # endif /* !MSWINCE */