gc4.14alpha1 tarball import gc4_14alpha1
authorIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 11:27:52 +0000 (15:27 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 11:27:52 +0000 (15:27 +0400)
13 files changed:
Makefile
Makefile.dj
README
alloc.c
blacklst.c
finalize.c
gc_cpp.h
gc_mark.h
gcconfig.h
include/gc_cpp.h
include/private/gcconfig.h
mark.c
version.h

index 2df25c4..ffd8128 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ AS=as $(ABI_FLAG)
 #  Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64)
 #  if you use something other than the default ABI on your machine.
 
-CFLAGS= -O -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION -DSILENT
+CFLAGS= -O -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DNO_EXECUTE_PERMISSION -DALL_INTERIOR_POINTERS -DSILENT
 
 # For dynamic library builds, it may be necessary to add flags to generate
 # PIC code, e.g. -fPIC on Linux.
@@ -275,16 +275,16 @@ mark_rts.o: $(srcdir)/mark_rts.c if_mach if_not_there $(UTILS)
 alloc.o: version.h
 
 cord/cordbscs.o: $(srcdir)/cord/cordbscs.c $(CORD_INCLUDE_FILES)
-       $(CC) $(CFLAGS) -c $(srcdir)/cord/cordbscs.c
+       $(CC) $(CFLAGS) -c -I$(srcdir) $(srcdir)/cord/cordbscs.c
        mv cordbscs.o cord/cordbscs.o
 #  not all compilers understand -o filename
 
 cord/cordxtra.o: $(srcdir)/cord/cordxtra.c $(CORD_INCLUDE_FILES)
-       $(CC) $(CFLAGS) -c $(srcdir)/cord/cordxtra.c
+       $(CC) $(CFLAGS) -c -I$(srcdir) $(srcdir)/cord/cordxtra.c
        mv cordxtra.o cord/cordxtra.o
 
 cord/cordprnt.o: $(srcdir)/cord/cordprnt.c $(CORD_INCLUDE_FILES)
-       $(CC) $(CFLAGS) -c $(srcdir)/cord/cordprnt.c
+       $(CC) $(CFLAGS) -c -I$(srcdir) $(srcdir)/cord/cordprnt.c
        mv cordprnt.o cord/cordprnt.o
 
 cord/cordtest: $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a $(UTILS)
index 8e0a66b..54f77db 100644 (file)
@@ -7,15 +7,23 @@
 #               and runs some tests of collector and cords.  Does not add cords or
 #       c++ interface to gc.a
 # cord/de$(EXE_SUFFIX) - builds dumb editor based on cords.
-CC=gcc
-CXX=gcc -x c++
-CXXLD=gxx
-RM=rm -f
-MV=mv
+ABI_FLAG=
+CC=gcc $(ABI_FLAG)
+CXX=gxx $(ABI_FLAG)
+AS=gcc -c -x assembler-with-cpp $(ABI_FLAG)
+#  The above doesn't work with gas, which doesn't run cpp.
+#  Define AS as `gcc -c -x assembler-with-cpp' instead.
+#  Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64)
+#  if you use something other than the default ABI on your machine.
+
+# special defines for DJGPP
+CXXLD=gxx $(ABI_FLAG)
 EXE_SUFFIX=.exe
-RANLIB=ranlib
 
-CFLAGS= -O -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DSILENT -DATOMIC_UNCOLLECTABLE
+CFLAGS= -O -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION -DSILENT
+
+# For dynamic library builds, it may be necessary to add flags to generate
+# PIC code, e.g. -fPIC on Linux.
 
 # Setjmp_test may yield overly optimistic results when compiled
 # without optimization.
@@ -29,8 +37,12 @@ CFLAGS= -O -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DSILENT -DATOMIC_UNCOLLECTABLE
 # -DSOLARIS_THREADS enables support for Solaris (thr_) threads.
 #   (Clients should also define SOLARIS_THREADS and then include
 #   gc.h before performing thr_ or dl* or GC_ operations.)
-#   This is broken on nonSPARC machines.
+#   Must also define -D_REENTRANT.
+# -D_SOLARIS_PTHREADS enables support for Solaris pthreads.
+#   Define SOLARIS_THREADS as well.
 # -DIRIX_THREADS enables support for Irix pthreads.  See README.irix.
+# -DLINUX_THREADS enables support for Xavier Leroy's Linux threads.
+#   see README.linux.  -D_REENTRANT may also be required.
 # -DALL_INTERIOR_POINTERS allows all pointers to the interior
 #   of objects to be recognized.  (See gc_priv.h for consequences.)
 # -DSMALL_CONFIG tries to tune the collector for small heap sizes,
@@ -78,9 +90,34 @@ CFLAGS= -O -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DSILENT -DATOMIC_UNCOLLECTABLE
 #   in a sepearte postpass, and hence their memory won't be reclaimed.
 #   Not recommended unless you are implementing a language that specifies
 #   these semantics.
+# -DFINALIZE_ON_DEMAND causes finalizers to be run only in response
+#   to explicit GC_invoke_finalizers() calls.
 # -DATOMIC_UNCOLLECTABLE includes code for GC_malloc_atomic_uncollectable.
 #   This is useful if either the vendor malloc implementation is poor,
 #   or if REDIRECT_MALLOC is used.
+# -DHBLKSIZE=ddd, where ddd is a power of 2 between 512 and 16384, explicitly
+#   sets the heap block size.  Each heap block is devoted to a single size and
+#   kind of object.  For the incremental collector it makes sense to match
+#   the most likely page size.  Otherwise large values result in more
+#   fragmentation, but generally better performance for large heaps.
+# -DUSE_MMAP use MMAP instead of sbrk to get new memory.
+#   Works for Solaris and Irix.
+# -DMMAP_STACKS (for Solaris threads) Use mmap from /dev/zero rather than
+#   GC_scratch_alloc() to get stack memory.
+# -DPRINT_BLACK_LIST Whenever a black list entry is added, i.e. whenever
+#   the garbage collector detects a value that looks almost, but not quite,
+#   like a pointer, print both the address containing the value, and the
+#   value of the near-bogus-pointer.  Can be used to identifiy regions of
+#   memory that are likely to contribute misidentified pointers.
+# -DOLD_BLOCK_ALLOC Use the old, possibly faster, large block
+#   allocation strategy.  The new strategy tries harder to minimize
+#   fragmentation, sometimes at the expense of spending more time in the
+#   large block allocator and/or collecting more frequently.
+#   If you expect the allocator to promtly use an explicitly expanded
+#   heap, this is highly recommended.
+#
+
+
 
 LIBGC_CFLAGS= -O -DNO_SIGNALS -DSILENT \
     -DREDIRECT_MALLOC=GC_malloc_uncollectable \
@@ -98,9 +135,9 @@ RANLIB= ranlib
 srcdir = .
 VPATH = $(srcdir)
 
-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 typd_mlc.o ptr_chck.o mallocx.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 irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.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 typd_mlc.c ptr_chck.c mallocx.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 irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c
 
 CORD_SRCS=  cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c cord/cord.h cord/ec.h cord/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC cord/SCOPTIONS.amiga cord/SMakefile.amiga
 
@@ -111,7 +148,8 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \
     gcconfig.h gc_mark.h include/gc_inl.h include/gc_inline.h gc.man \
     threadlibs.c if_mach.c if_not_there.c gc_cpp.cc gc_cpp.h weakpointer.h \
     gcc_support.c mips_ultrix_mach_dep.s include/gc_alloc.h gc_alloc.h \
-    $(CORD_SRCS)
+    include/new_gc_alloc.h include/javaxfc.h sparc_sunos4_mach_dep.s \
+    solaris_threads.h $(CORD_SRCS)
 
 OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
            README test.c test_cpp.cc setjmp_t.c SMakefile.amiga \
@@ -126,12 +164,14 @@ OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
            include/gc_cpp.h Mac_files/datastart.c Mac_files/dataend.c \
            Mac_files/MacOS_config.h Mac_files/MacOS_Test_config.h \
            add_gc_prefix.c README.solaris2 README.sgi README.hp README.uts \
-          win32_threads.c NT_THREADS_MAKEFILE gc.mak README.dj Makefile.dj
+          win32_threads.c NT_THREADS_MAKEFILE gc.mak README.dj Makefile.dj \
+          README.alpha README.linux version.h Makefile.DLLs \
+          WCC_MAKEFILE
 
 CORD_INCLUDE_FILES= $(srcdir)/gc.h $(srcdir)/cord/cord.h $(srcdir)/cord/ec.h \
            $(srcdir)/cord/private/cord_pos.h
 
-UTILS= if_mach$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX) threadlibs$(EXE_SUFFIX)
+UTILS= if_mach$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX)
 
 # Libraries needed for curses applications.  Only needed for de.
 CURSES= -lcurses -ltermlib
@@ -163,128 +203,160 @@ mark.o typd_mlc.o finalize.o: $(srcdir)/gc_mark.h
 
 base_lib gc.a: $(OBJS) dyn_load.o $(UTILS)
        echo > base_lib
-       $(RM) on_sparc_sunos5
-       ./if_mach SPARC SUNOS5 touch on_sparc_sunos5
+       rm -f on_sparc_sunos5_1
+       ./if_mach SPARC SUNOS5 touch on_sparc_sunos5_1
        ./if_mach SPARC SUNOS5 $(AR) rus gc.a $(OBJS) dyn_load.o
-       ./if_not_there on_sparc_sunos5 $(AR) ru gc.a $(OBJS) dyn_load.o
-       -./if_not_there on_sparc_sunos5 $(RANLIB) gc.a
+       ./if_not_there on_sparc_sunos5_1 $(AR) ru gc.a $(OBJS) dyn_load.o
+       -./if_not_there on_sparc_sunos5_1 $(RANLIB) gc.a
 #      ignore ranlib failure; that usually means it doesn't exist, and isn't needed
 
-libgc.a: 
-       make CFLAGS="$(LIBGC_CFLAGS)" clean gc.a gcc_support.o
-       $(MV) gc.a libgc.a
-       -$(RM) on_sparc_sunos5
-       ./if_mach SPARC SUNOS5 touch on_sparc_sunos5
-       ./if_mach SPARC SUNOS5 $(AR) rus libgc.a gcc_support.o
-       ./if_not_there on_sparc_sunos5 $(AR) ru libgc.a gcc_support.o
-       -./if_not_there on_sparc_sunos5 $(RANLIB) libgc.a
-
 cords: $(CORD_OBJS) cord/cordtest$(EXE_SUFFIX) $(UTILS)
-       -$(RM) on_sparc_sunos5
-       ./if_mach SPARC SUNOS5 touch on_sparc_sunos5
+       rm -f on_sparc_sunos5_3
+       ./if_mach SPARC SUNOS5 touch on_sparc_sunos5_3
        ./if_mach SPARC SUNOS5 $(AR) rus gc.a $(CORD_OBJS)
-       ./if_not_there on_sparc_sunos5 $(AR) ru gc.a $(CORD_OBJS)
-       -./if_not_there on_sparc_sunos5 $(RANLIB) gc.a
+       ./if_not_there on_sparc_sunos5_3 $(AR) ru gc.a $(CORD_OBJS)
+       -./if_not_there on_sparc_sunos5_3 $(RANLIB) gc.a
 
 gc_cpp.o: $(srcdir)/gc_cpp.cc $(srcdir)/gc_cpp.h $(srcdir)/gc.h Makefile
        $(CXX) -c $(CXXFLAGS) $(srcdir)/gc_cpp.cc
 
-test_cpp: $(srcdir)/test_cpp.cc $(srcdir)/gc_cpp.h gc_cpp.o $(srcdir)/gc.h \
+test_cpp$(EXE_SUFFIX): $(srcdir)/test_cpp.cc $(srcdir)/gc_cpp.h gc_cpp.o $(srcdir)/gc.h \
 base_lib $(UTILS)
-       -$(RM) test_cpp test_cpp$(EXE_SUFFIX)
+       rm -f test_cpp test_cpp$(EXE_SUFFIX)
        ./if_mach HP_PA "" $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o gc.a -ldld
-       ./if_not_there test_cpp$(EXE_SUFFIX) $(CXXLD) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o gc.a
-       $(RM) test_cpp
-
-c++: gc_cpp.o $(srcdir)/gc_cpp.h test_cpp
-       -$(RM) on_sparc_sunos5
-       $(AR) ru gc.a gc_cpp.o
-       $(RANLIB) gc.a
+       ./if_not_there test_cpp$(EXE_SUFFIX) $(CXXLD) $(CXXFLAGS) -o test_cpp$(EXE_SUFFIX) $(srcdir)/test_cpp.cc gc_cpp.o gc.a
+       rm -f test_cpp
+
+c++: gc_cpp.o $(srcdir)/gc_cpp.h test_cpp$(EXE_SUFFIX)
+       rm -f on_sparc_sunos5_4
+       ./if_mach SPARC SUNOS5 touch on_sparc_sunos5_4
+       ./if_mach SPARC SUNOS5 $(AR) rus gc.a gc_cpp.o
+       ./if_not_there on_sparc_sunos5_4 $(AR) ru gc.a gc_cpp.o
+       -./if_not_there on_sparc_sunos5_4 $(RANLIB) gc.a
        ./test_cpp$(EXE_SUFFIX) 1
        echo > c++
 
 dyn_load_sunos53.o: dyn_load.c
        $(CC) $(CFLAGS) -DSUNOS53_SHARED_LIB -c $(srcdir)/dyn_load.c -o $@
 
-mach_dep.o: $(srcdir)/mach_dep.c
-       -$(RM) mach_dep.o
-       $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
-
-mark_rts.o: $(srcdir)/mark_rts.c
-       -$(RM) mark_rts.o
-       $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
+# SunOS5 shared library version of the collector
+sunos5gc.so: $(OBJS) dyn_load_sunos53.o
+       $(CC) -G -o sunos5gc.so $(OBJS) dyn_load_sunos53.o -ldl
+       ln sunos5gc.so libgc.so
+
+# Alpha/OSF shared library version of the collector
+libalphagc.so: $(OBJS)
+       ld -shared -o libalphagc.so $(OBJS) dyn_load.o -lc
+       ln libalphagc.so libgc.so
+
+# IRIX shared library version of the collector
+libirixgc.so: $(OBJS) dyn_load.o
+       ld -shared $(ABI_FLAG) -o libirixgc.so $(OBJS) dyn_load.o -lc
+       ln libirixgc.so libgc.so
+
+# Linux shared library version of the collector
+liblinuxgc.so: $(OBJS) dyn_load.o
+       gcc -shared -o liblinuxgc.so $(OBJS) dyn_load.o -lo
+       ln liblinuxgc.so libgc.so
+
+mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ultrix_mach_dep.s $(srcdir)/rs6000_mach_dep.s $(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 ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
+       ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s
+       ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
+       ./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
+
+mark_rts.o: $(srcdir)/mark_rts.c if_mach if_not_there $(UTILS)
+       rm -f mark_rts.o
+       -./if_mach ALPHA OSF1 $(CC) -c $(CFLAGS) -Wo,-notail $(srcdir)/mark_rts.c
+       ./if_not_there mark_rts.o $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
+#      Work-around for DEC optimizer tail recursion elimination bug.
+#  The ALPHA-specific line should be removed if gcc is used.
+
+alloc.o: version.h
 
 cord/cordbscs.o: $(srcdir)/cord/cordbscs.c $(CORD_INCLUDE_FILES)
-       $(CC) $(CFLAGS) -c $(srcdir)/cord/cordbscs.c
-       $(MV) cordbscs.o cord/cordbscs.o
+       $(CC) $(CFLAGS) -c -I$(srcdir) $(srcdir)/cord/cordbscs.c
+       mv cordbscs.o cord/cordbscs.o
 #  not all compilers understand -o filename
 
 cord/cordxtra.o: $(srcdir)/cord/cordxtra.c $(CORD_INCLUDE_FILES)
-       $(CC) $(CFLAGS) -c $(srcdir)/cord/cordxtra.c
-       $(MV) cordxtra.o cord/cordxtra.o
+       $(CC) $(CFLAGS) -c -I$(srcdir) $(srcdir)/cord/cordxtra.c
+       mv cordxtra.o cord/cordxtra.o
 
 cord/cordprnt.o: $(srcdir)/cord/cordprnt.c $(CORD_INCLUDE_FILES)
-       $(CC) $(CFLAGS) -c $(srcdir)/cord/cordprnt.c
-       $(MV) cordprnt.o cord/cordprnt.o
-
-cord/cordtest$(EXE_SUFFIX): $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a $(UTILS)
-       -$(RM) cord/cordtest$(EXE_SUFFIX)
-       $(CC) $(CFLAGS) -o cordtest $(srcdir)/cord/cordtest.c\
-                $(CORD_OBJS) gc.a
-       ./if_not_there cord/cordtest$(EXE_SUFFIX) \
-               $(MV) cordtest$(EXE_SUFFIX) cord/cordtest$(EXE_SUFFIX)
-
-cord/de$(EXE_SUFFIX): $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
-       -$(RM) cord/de$(EXE_SUFFIX)
-       ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c\
-cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb
-       ./if_mach HP_PA "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c\
-cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld
-       ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c\
-cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
-       ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c\
-cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
-       ./if_not_there cord/de $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c\
-cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES)
-       ./if_not_there cord/de$(EXE_SUFFIX) \
-               $(MV) de$(EXE_SUFFIX) cord/de$(EXE_SUFFIX)
+       $(CC) $(CFLAGS) -c -I$(srcdir) $(srcdir)/cord/cordprnt.c
+       mv cordprnt.o cord/cordprnt.o
+
+cord/cordtest$(EXE_SUFFIX): $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a $(UTILS) /tmp
+       rm -f cord/cordtest$(EXE_SUFFIX)
+       ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/cordtest$(EXE_SUFFIX) $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a -lucb
+       ./if_mach HP_PA "" $(CC) $(CFLAGS) -o cord/cordtest$(EXE_SUFFIX) $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a -ldld
+       ./if_not_there cord/cordtest$(EXE_SUFFIX) $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a
+       rm -f cord/cordtest cordtest
+       -mv cordtest$(EXE_SUFFIX) cord/
+
+/tmp: $(UTILS)
+       ./if_not_there /tmp mkdir /tmp
+
+cord/de$(EXE_SUFFIX): $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(UTILS)
+       rm -f cord/de cord/de$(EXE_SUFFIX)
+       ./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 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld
+       ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
+       ./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
+       ./if_not_there cord/de$(EXE_SUFFIX) $(CC) $(CFLAGS) -o cord/de$(EXE_SUFFIX) $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES)
 
 if_mach$(EXE_SUFFIX): $(srcdir)/if_mach.c $(srcdir)/gcconfig.h
+       rm -f if_mach if_mach$(EXE_SUFFIX)
        $(CC) $(CFLAGS) -o if_mach $(srcdir)/if_mach.c
-       -$(RM) if_mach
+       rm -f if_mach
 
 threadlibs$(EXE_SUFFIX): $(srcdir)/threadlibs.c $(srcdir)/gcconfig.h Makefile
+       rm -f threadlibs threadlibs$(EXE_SUFFIX)
        $(CC) $(CFLAGS) -o threadlibs $(srcdir)/threadlibs.c
-       -$(RM) threadlibs
+       rm -f threadlibs
 
 if_not_there$(EXE_SUFFIX): $(srcdir)/if_not_there.c
+       rm -f if_not_there if_not_there$(EXE_SUFFIX)
        $(CC) $(CFLAGS) -o if_not_there $(srcdir)/if_not_there.c
-       -$(RM) if_not_there
-
-clean:
-       -$(RM) gc.a *.o
-       -$(RM) *.o
-       -$(RM) gctest gctest_dyn_link test_cpp \
-             setjmp_test  mon.out gmon.out a.out core if_not_there if_mach \
-             $(CORD_OBJS) cordtest cord/cordtest de cord/de
-       -$(RM) gctest$(EXE_SUFFIX) gctest_dyn_link$(EXE_SUFFIX) test_cpp$(EXE_SUFFIX) \
-             setjmp_test$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX) if_mach$(EXE_SUFFIX) \
-             cord/cordtest$(EXE_SUFFIX)
-       -$(RM) *~
-
-gctest$(EXE_SUFFIX): test.o gc.a
-       -$(RM) gctest$(EXE_SUFFIX)
-       $(CC) $(CFLAGS) -o gctest test.o gc.a
-       $(RM) gctest
+       rm -f if_not_there
+
+# Clean removes *.o several times,
+# because as the first one doesn't seem to get them all!
+clean: 
+       rm -f gc.a *.o
+       rm -f *.o
+       rm -f *.o
+       rm -f cord/*.o
+       rm -f gctest gctest_dyn_link test_cpp
+       rm -f setjmp_test  mon.out gmon.out a.out core if_not_there if_mach
+       rm -f threadlibs $(CORD_OBJS) cordtest cord/cordtest de cord/de
+       rm -f gctest$(EXE_SUFFIX) gctest_dyn_link$(EXE_SUFFIX) test_cpp$(EXE_SUFFIX)
+       rm -f setjmp_test$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX) if_mach$(EXE_SUFFIX)
+       rm -f threadlibs$(EXE_SUFFIX) cord/cordtest$(EXE_SUFFIX)
+       -rm -f *~
+
+gctest$(EXE_SUFFIX): test.o gc.a if_mach$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX)
+       rm -f gctest gctest$(EXE_SUFFIX)
+       ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o gctest  test.o gc.a -lucb
+       ./if_mach HP_PA "" $(CC) $(CFLAGS) -o gctest  test.o gc.a -ldld
+       ./if_not_there gctest$(EXE_SUFFIX) $(CC) $(CFLAGS) -o gctest$(EXE_SUFFIX) test.o gc.a
+       rm -f gctest
 
 # If an optimized setjmp_test generates a segmentation fault,
 # odds are your compiler is broken.  Gctest may still work.
 # Try compiling setjmp_t.c unoptimized.
 setjmp_test$(EXE_SUFFIX): $(srcdir)/setjmp_t.c $(srcdir)/gc.h \
                if_mach$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX)
-       -$(RM) setjmp_test$(EXE_SUFFIX)
+       rm -f setjmp_test$(EXE_SUFFIX)
        $(CC) $(CFLAGS) -o setjmp_test $(srcdir)/setjmp_t.c
-       $(RM) setjmp_test
+       rm -f setjmp_test
 
 test:  KandRtest cord/cordtest$(EXE_SUFFIX)
        ./cord/cordtest$(EXE_SUFFIX)
@@ -294,3 +366,71 @@ KandRtest: setjmp_test$(EXE_SUFFIX) gctest$(EXE_SUFFIX)
        ./setjmp_test$(EXE_SUFFIX)
        ./gctest$(EXE_SUFFIX)
 
+add_gc_prefix$(EXE_SUFFIX): add_gc_prefix.c
+       $(CC) -o add_gc_prefix$(EXE_SUFFIX) $(srcdir)/add_gc_prefix.c
+       rm -f add_gc_prefix
+
+gc.tar: $(SRCS) $(OTHER_FILES) add_gc_prefix
+       ./add_gc_prefix$(EXE_SUFFIX) $(SRCS) $(OTHER_FILES) > /tmp/gc.tar-files
+       (cd $(srcdir)/.. ; tar cvfh - `cat /tmp/gc.tar-files`) > gc.tar
+
+pc_gc.tar: $(SRCS) $(OTHER_FILES)
+       tar cvfX pc_gc.tar pc_excludes $(SRCS) $(OTHER_FILES)
+
+floppy: pc_gc.tar
+       -mmd a:/cord
+       -mmd a:/cord/private
+       -mmd a:/include
+       -mmd a:/include/private
+       mkdir /tmp/pc_gc
+       cat pc_gc.tar | (cd /tmp/pc_gc; tar xvf -)
+       -mcopy -tmn /tmp/pc_gc/* a:
+       -mcopy -tmn /tmp/pc_gc/cord/* a:/cord
+       -mcopy -mn /tmp/pc_gc/cord/de_win.ICO a:/cord
+       -mcopy -tmn /tmp/pc_gc/cord/private/* a:/cord/private
+       -mcopy -tmn /tmp/pc_gc/include/* a:/include
+       -mcopy -tmn /tmp/pc_gc/include/private/* a:/include/private
+       rm -r /tmp/pc_gc
+
+gc.tar.Z: gc.tar
+       compress gc.tar
+
+gc.tar.gz: gc.tar
+       gzip gc.tar
+
+lint: $(CSRCS) test.c
+       lint -DLINT $(CSRCS) test.c | egrep -v "possible pointer alignment problem|abort|exit|sbrk|mprotect|syscall"
+
+# BTL: added to test shared library version of collector.
+# Currently works only under SunOS5.  Requires GC_INIT call from statically
+# loaded client code.
+ABSDIR = `pwd`
+gctest_dyn_link: test.o libgc.so
+       $(CC) -L$(ABSDIR) -R$(ABSDIR) -o gctest_dyn_link test.o -lgc -ldl -lthread
+
+gctest_irix_dyn_link: test.o libirixgc.so
+       $(CC) -L$(ABSDIR) -o gctest_irix_dyn_link test.o -lirixgc
+
+test_dll.o: test.c libgc_globals.h
+       $(CC) $(CFLAGS) -DGC_USE_DLL -c test.c -o test_dll.o
+
+test_dll: test_dll.o libgc_dll.a libgc.dll
+       $(CC) test_dll.o -L$(ABSDIR) -lgc_dll -o test_dll
+
+SYM_PREFIX-libgc=GC
+
+# Uncomment the following line to build a GNU win32 DLL
+# include Makefile.DLLs
+
+reserved_namespace: $(SRCS)
+       for file in $(SRCS) test.c test_cpp.cc; do \
+               sed s/GC_/_GC_/g < $$file > tmp; \
+               cp tmp $$file; \
+               done
+
+user_namespace: $(SRCS)
+       for file in $(SRCS) test.c test_cpp.cc; do \
+               sed s/_GC_/GC_/g < $$file > tmp; \
+               cp tmp $$file; \
+               done
+
diff --git a/README b/README
index 9ddc72d..b245beb 100644 (file)
--- a/README
+++ b/README
@@ -11,7 +11,7 @@ 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.
 
-This is version 4.13 of a conservative garbage collector for C and C++.
+This is version 4.14alpha1 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
@@ -1410,6 +1410,29 @@ Since alpha3:
  - Integrated Phillip Musumeci's FreeBSD/ELF fixes.
  - -DIRIX_THREADS was broken with the -o32 ABI (typo in gc_priv.h>
 
+Since 4.13:
+ - Fixed GC_print_source_ptr to not use a prototype.
+ - generalized CYGWIN test.
+ - gc::new did the wrong thing with PointerFreeGC placement.
+   (Thanks to Rauli Ruohonen.)
+ - In the ALL_INTERIOR_POINTERS (default) case, some callee-save register
+   values could fail to be scanned if the register was saved and
+   reused in a GC frame.  This showed up in verbose mode with gctest
+   compiled with an unreleased SGI compiler.  I vaguely recall an old
+   bug report that may have been related.  The bug was probably quite old.
+   (The problem was that the stack scanning could be deferred until
+   after the relevant frame was overwritten, and the new save location
+   might be outside the scanned area.  Fixed by more eager stack scanning.)
+ - PRINT_BLACK_LIST had some problems.  A few source addresses were garbage.
+ - Removed a prototype in code that shouldn't assume prototype support.
+ - Replaced Makefile.dj and added -I flags to cord make targets.
+   (Thanks to Gary Leavens.)
+ - GC_try_to_collect was broken with the nonincremental collector.
+ - gc_cleanup destructors could pass the wrong address to
+   GC_register_finalizer_ignore_self in the presence of multiple
+   inheritance.  (Thanks to Darrell Schiebel.)
+
+
 To do:
  - Very large root set sizes (> 16 MB or so) could cause the collector
    to abort with an unexpected mark stack overflow.  (Thanks again to
diff --git a/alloc.c b/alloc.c
index d00ff07..7e1f03e 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -85,6 +85,7 @@ GC_bool GC_dont_expand = 0;
 word GC_free_space_divisor = 4;
 
 extern GC_bool GC_collection_in_progress();
+               /* Collection is in progress, or was abandoned. */
 
 int GC_never_stop_func GC_PROTO((void)) { return(0); }
 
@@ -271,7 +272,7 @@ void GC_maybe_gc()
 GC_bool GC_try_to_collect_inner(stop_func)
 GC_stop_func stop_func;
 {
-    if (GC_collection_in_progress()) {
+    if (GC_incremental && GC_collection_in_progress()) {
 #   ifdef PRINTSTATS
        GC_printf0(
            "GC_try_to_collect_inner: finishing collection in progress\n");
@@ -341,7 +342,7 @@ int n;
 {
     register int i;
     
-    if (GC_collection_in_progress()) {
+    if (GC_incremental && GC_collection_in_progress()) {
        for (i = GC_deficit; i < GC_RATE*n; i++) {
            if (GC_mark_some()) {
                /* Need to finish a collection */
@@ -385,9 +386,7 @@ int GC_collect_a_little GC_PROTO(())
 /*
  * Assumes lock is held, signals are disabled.
  * We stop the world.
- * If final is TRUE, then we finish the collection, no matter how long
- * it takes.
- * Otherwise we may fail and return FALSE if this takes too long.
+ * If stop_func() ever returns TRUE, we may fail and return FALSE.
  * Increment GC_gc_no if we succeed.
  */
 GC_bool GC_stopped_mark(stop_func)
index 44455e5..0d623c0 100644 (file)
@@ -63,11 +63,16 @@ ptr_t p;
 void (*GC_print_heap_obj)(/* char * s, ptr_t p */) =
                                GC_default_print_heap_obj_proc;
 
-void GC_print_source_ptr(ptr_t p)
+void GC_print_source_ptr(p)
+ptr_t p;
 {
     ptr_t base = GC_base(p);
     if (0 == base) {
-       GC_err_printf0("in root set");
+       if (0 == p) {
+           GC_err_printf0("in register");
+       } else {
+           GC_err_printf0("in root set");
+       }
     } else {
        GC_err_printf0("in object at ");
        (*GC_print_heap_obj)(base);
index 8a65b93..f33ae73 100644 (file)
@@ -278,7 +278,7 @@ ptr_t p;
     for (q = p; q <= scan_limit; q += ALIGNMENT) {
        r = *(ptr_t *)q;
        if (r < p || r > target_limit) {
-           GC_PUSH_ONE_HEAP((word)r);
+           GC_PUSH_ONE_HEAP((word)r, q);
        }
     }
 }
index a591d36..ad7df5d 100644 (file)
--- a/gc_cpp.h
+++ b/gc_cpp.h
@@ -213,6 +213,8 @@ inline void* gc::operator new( size_t size ) {
 inline void* gc::operator new( size_t size, GCPlacement gcp ) {
     if (gcp == GC) 
         return GC_MALLOC( size );
+    else if (gcp == PointerFreeGC)
+       return GC_MALLOC_ATOMIC( size );
     else
         return GC_MALLOC_UNCOLLECTABLE( size );}
 
@@ -235,7 +237,7 @@ inline void gc::operator delete[]( void* obj ) {
 
 
 inline gc_cleanup::~gc_cleanup() {
-    GC_REGISTER_FINALIZER_IGNORE_SELF( 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 d19f7f2..406cba6 100644 (file)
--- a/gc_mark.h
+++ b/gc_mark.h
@@ -178,18 +178,24 @@ mse * GC_signal_mark_stack_overflow();
   exit_label: ; \
 }
 
+#ifdef PRINT_BLACK_LIST
+#   define PUSH_ONE_CHECKED(p, ip, source) \
+       GC_push_one_checked(p, ip, (ptr_t)(source))
+#else
+#   define PUSH_ONE_CHECKED(p, ip, source) \
+       GC_push_one_checked(p, ip)
+#endif
 
 /*
  * Push a single value onto mark stack. Mark from the object pointed to by p.
- * GC_push_one is normally called by GC_push_regs, and thus must be defined.
  * 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) \
+# define GC_PUSH_ONE_STACK(p, source) \
     if ((ptr_t)(p) >= GC_least_plausible_heap_addr     \
         && (ptr_t)(p) < GC_greatest_plausible_heap_addr) {     \
-        GC_push_one_checked(p,TRUE);   \
+        PUSH_ONE_CHECKED(p, TRUE, source);     \
     }
 
 /*
@@ -201,10 +207,10 @@ mse * GC_signal_mark_stack_overflow();
 # else
 #   define AIP FALSE
 # endif
-# define GC_PUSH_ONE_HEAP(p) \
+# define GC_PUSH_ONE_HEAP(p,source) \
     if ((ptr_t)(p) >= GC_least_plausible_heap_addr     \
         && (ptr_t)(p) < GC_greatest_plausible_heap_addr) {     \
-        GC_push_one_checked(p,AIP);    \
+        PUSH_ONE_CHECKED(p,AIP,source);        \
     }
 
 /*
@@ -238,8 +244,8 @@ typedef int mark_state_t;   /* Current state of marking, as follows:*/
                                
                                /* Invariant I: all roots and marked    */
                                /* objects p are either dirty, or point */
-                               /* objects q that are either marked or  */
-                               /* a pointer to q appears in a range    */
+                               /* to objects q that are either marked  */
+                               /* or a pointer to q appears in a range */
                                /* on the mark stack.                   */
 
 # define MS_NONE 0             /* No marking in progress. I holds.     */
index 7fecb73..47545ae 100644 (file)
 #   define mach_type_known
 # endif
 # if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
-     || defined(_WIN32) && !defined(__CYGWIN32__)
+     || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
 #   define I386
 #   define MSWIN32     /* or Win32s */
 #   define mach_type_known
 #   endif
 #   define mach_type_known
 # endif
-# if defined(__CYGWIN32__)
+# if defined(__CYGWIN32__) || defined(__CYGWIN__)
 #   define I386
 #   define CYGWIN32
 #   define mach_type_known
 #   endif
 #   ifdef LINUX
 #     define OS_TYPE "LINUX"
-#     define STACKBOTTOM ((ptr_t)0x80000000)
+#     define HEURISTIC1
+#     undef STACK_GRAN
+#     define STACK_GRAN 0x10000000
 #     define DATASTART GC_data_start
       extern int _end;
 #     define DATAEND (&_end)
index a591d36..ad7df5d 100644 (file)
@@ -213,6 +213,8 @@ inline void* gc::operator new( size_t size ) {
 inline void* gc::operator new( size_t size, GCPlacement gcp ) {
     if (gcp == GC) 
         return GC_MALLOC( size );
+    else if (gcp == PointerFreeGC)
+       return GC_MALLOC_ATOMIC( size );
     else
         return GC_MALLOC_UNCOLLECTABLE( size );}
 
@@ -235,7 +237,7 @@ inline void gc::operator delete[]( void* obj ) {
 
 
 inline gc_cleanup::~gc_cleanup() {
-    GC_REGISTER_FINALIZER_IGNORE_SELF( 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 7fecb73..47545ae 100644 (file)
 #   define mach_type_known
 # endif
 # if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
-     || defined(_WIN32) && !defined(__CYGWIN32__)
+     || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
 #   define I386
 #   define MSWIN32     /* or Win32s */
 #   define mach_type_known
 #   endif
 #   define mach_type_known
 # endif
-# if defined(__CYGWIN32__)
+# if defined(__CYGWIN32__) || defined(__CYGWIN__)
 #   define I386
 #   define CYGWIN32
 #   define mach_type_known
 #   endif
 #   ifdef LINUX
 #     define OS_TYPE "LINUX"
-#     define STACKBOTTOM ((ptr_t)0x80000000)
+#     define HEURISTIC1
+#     undef STACK_GRAN
+#     define STACK_GRAN 0x10000000
 #     define DATASTART GC_data_start
       extern int _end;
 #     define DATAEND (&_end)
diff --git a/mark.c b/mark.c
index 0fffcf3..2febda3 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -113,6 +113,9 @@ GC_bool GC_mark_stack_too_small = FALSE;
 GC_bool GC_objects_are_marked = FALSE; /* Are there collectable marked */
                                        /* objects in the heap?         */
 
+/* Is a collection in progress?  Note that this can return true in the */
+/* nonincremental case, if a collection has been abandoned and the     */
+/* mark state is now MS_INVALID.                                       */
 GC_bool GC_collection_in_progress()
 {
     return(GC_mark_state != MS_NONE);
@@ -304,9 +307,12 @@ GC_bool GC_mark_some()
                GC_mark_from_mark_stack();
                return(FALSE);
            }
-           if (scan_ptr == 0
-               && (GC_mark_state == MS_INVALID || GC_mark_stack_too_small)) {
-               alloc_mark_stack(2*GC_mark_stack_size);
+           if (scan_ptr == 0 && GC_mark_state == MS_INVALID) {
+               /* About to start a heap scan for marked objects. */
+               /* Mark stack is empty.  OK to reallocate.        */
+               if (GC_mark_stack_too_small) {
+                   alloc_mark_stack(2*GC_mark_stack_size);
+               }
                GC_mark_state = MS_PARTIALLY_INVALID;
            }
            scan_ptr = GC_push_next_marked(scan_ptr);
@@ -393,6 +399,7 @@ mse * GC_signal_mark_stack_overflow(msp)
 mse * msp;
 {
     GC_mark_state = MS_INVALID;
+    GC_mark_stack_too_small = TRUE;
 #   ifdef PRINTSTATS
        GC_printf1("Mark stack overflow; current size = %lu entries\n",
                    GC_mark_stack_size);
@@ -657,7 +664,7 @@ int all;
 # endif
 word p;
 {
-    GC_PUSH_ONE_STACK(p);
+    GC_PUSH_ONE_STACK(p, 0);
 }
 
 # ifdef __STDC__
@@ -696,13 +703,18 @@ register GC_bool interior_ptrs;
         displ = HBLKDISPL(p);
         map_entry = MAP_ENTRY((hhdr -> hb_map), displ);
         if (map_entry == OBJ_INVALID) {
-          if (interior_ptrs) {
-            r = BASE(p);
-           displ = BYTES_TO_WORDS(HBLKDISPL(r));
-           if (r == 0) hhdr = 0;
-          } else {
-            hhdr = 0;
-          }
+#        ifndef ALL_INTERIOR_POINTERS
+            if (interior_ptrs) {
+              r = BASE(p);
+             displ = BYTES_TO_WORDS(HBLKDISPL(r));
+             if (r == 0) hhdr = 0;
+            } else {
+              hhdr = 0;
+            }
+#        else
+           /* map already reflects interior pointers */
+           hhdr = 0;
+#        endif
         } else {
           displ = BYTES_TO_WORDS(displ);
           displ -= map_entry;
@@ -778,17 +790,13 @@ void GC_print_trace(word gc_no, GC_bool lock)
 
 /*
  * A version of GC_push_all that treats all interior pointers as valid
+ * and scans the entire region immediately, in case the contents
+ * change.
  */
-void GC_push_all_stack(bottom, top)
+void GC_push_all_eager(bottom, top)
 ptr_t bottom;
 ptr_t top;
 {
-# ifdef ALL_INTERIOR_POINTERS
-    GC_push_all(bottom, top);
-#   ifdef TRACE_BUF
-        GC_add_trace_entry("GC_push_all_stack", bottom, top);
-#   endif
-# else
     word * b = (word *)(((long) bottom + ALIGNMENT-1) & ~(ALIGNMENT-1));
     word * t = (word *)(((long) top) & ~(ALIGNMENT-1));
     register word *p;
@@ -805,10 +813,49 @@ ptr_t top;
       lim = t - 1 /* longword */;
       for (p = b; p <= lim; p = (word *)(((char *)p) + ALIGNMENT)) {
        q = *p;
-       GC_PUSH_ONE_STACK(q);
+       GC_PUSH_ONE_STACK(q, p);
       }
 #   undef GC_greatest_plausible_heap_addr
 #   undef GC_least_plausible_heap_addr
+}
+
+/*
+ * A version of GC_push_all that treats all interior pointers as valid
+ * and scans part of the area immediately, to make sure that saved
+ * register values are not lost.
+ */
+void GC_push_all_stack(bottom, top)
+ptr_t bottom;
+ptr_t top;
+{
+# ifdef 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.                */
+    /* The rest of the marking can be deferred until later.            */
+    ptr_t mid;
+#   ifdef STACK_GROWS_DOWN
+       mid = bottom + 1024;
+       if (mid < top) {
+           GC_push_all_eager(bottom, mid);
+           GC_push_all(mid - sizeof(ptr_t), top);
+       } else {
+           GC_push_all_eager(bottom, top);
+       }
+#   else /* STACK_GROWS_UP */
+       mid = top - 1024;
+       if (mid > bottom) {
+           GC_push_all_eager(mid, top);
+           GC_push_all(bottom, mid + sizeof(ptr_t));
+       } else {
+           GC_push_all_eager(bottom, top);
+       }
+#   endif /* STACK_GROWS_UP */
+# else
+    GC_push_all_eager(bottom, top);
+# endif
+# ifdef TRACE_BUF
+      GC_add_trace_entry("GC_push_all_stack", bottom, top);
 # endif
 }
 
@@ -840,7 +887,7 @@ register hdr * hhdr;
            while(mark_word != 0) {
              if (mark_word & 1) {
                  q = p[i];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i);
              }
              i++;
              mark_word >>= 1;
@@ -881,9 +928,9 @@ register hdr * hhdr;
            while(mark_word != 0) {
              if (mark_word & 1) {
                  q = p[i];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i);
                  q = p[i+1];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i);
              }
              i += 2;
              mark_word >>= 2;
@@ -923,13 +970,13 @@ register hdr * hhdr;
            while(mark_word != 0) {
              if (mark_word & 1) {
                  q = p[i];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i);
                  q = p[i+1];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i + 1);
                  q = p[i+2];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i + 2);
                  q = p[i+3];
-                 GC_PUSH_ONE_HEAP(q);
+                 GC_PUSH_ONE_HEAP(q, p + i + 3);
              }
              i += 4;
              mark_word >>= 4;
index 1f20252..f3b69f0 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
 #define GC_VERSION_MAJOR 4
-#define GC_VERSION_MINOR 13
-#define GC_ALPHA_VERSION GC_NOT_ALPHA
+#define GC_VERSION_MINOR 14
+#define GC_ALPHA_VERSION 1
 
 #   define GC_NOT_ALPHA 0xff