]> granicus.if.org Git - gc/commitdiff
gc5.0alpha4 tarball import gc5_0alpha4
authorHans Boehm <boehm@acm.org>
Sat, 30 Oct 1999 00:00:00 +0000 (00:00 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 17 May 2014 14:05:05 +0000 (18:05 +0400)
32 files changed:
Makefile
NT_THREADS_MAKEFILE [changed from symlink to file mode: 0644]
README
README.QUICK
README.hp
allchblk.c
alloc.c
blacklst.c
cord/cord.h
cord/gc.h
dbg_mlc.c
dyn_load.c
gc.h
gc_priv.h
gcconfig.h
hpux_irix_threads.c [moved from irix_threads.c with 85% similarity]
hpux_test_and_clear.s [new file with mode: 0644]
include/gc.h
include/gc_copy_descr.h [moved from gc_copy_descr.h with 100% similarity]
include/gc_nursery.h [moved from nursery.h with 100% similarity]
include/new_gc_alloc.h
include/private/gc_priv.h
mach_dep.c
mark.c
mark_rts.c
misc.c
nursery.c
os_dep.c
reclaim.c
test.c
threadlibs.c
version.h

index cfbfc452871ea257f165acaaa614f0a5114115b9..d6eab33f088f7a69c21f8677565bce55ff4bedd6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,9 @@
 #               and runs some tests of collector and cords.  Does not add cords or
 #       c++ interface to gc.a
 # cord/de - builds dumb editor based on cords.
-ABI_FLAG=
+ABI_FLAG= 
 CC=cc $(ABI_FLAG)
-CXX=CC $(ABI_FLAG)
+CXX=g++ $(ABI_FLAG)
 AS=as $(ABI_FLAG)
 #  The above doesn't work with gas, which doesn't run cpp.
 #  Define AS as `gcc -c -x assembler-with-cpp' instead.
@@ -35,6 +35,8 @@ CFLAGS= -O -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DNO_EXECUTE_PERMISSION -DALL_INT
 # -D_SOLARIS_PTHREADS enables support for Solaris pthreads.
 #   Define SOLARIS_THREADS as well.
 # -DIRIX_THREADS enables support for Irix pthreads.  See README.irix.
+# -DHPUX_THREADS enables support for HP/UX 11 pthreads.
+#  Also requires -D_REENTRANT. See README.hp.
 # -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
@@ -149,9 +151,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 linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.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 hpux_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 linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.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 hpux_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
 
@@ -163,7 +165,7 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \
     threadlibs.c if_mach.c if_not_there.c gc_cpp.cc gc_cpp.h weakpointer.h \
     gcc_support.c mips_ultrix_mach_dep.s include/gc_alloc.h gc_alloc.h \
     include/new_gc_alloc.h include/javaxfc.h sparc_sunos4_mach_dep.s \
-    solaris_threads.h backptr.h $(CORD_SRCS)
+    solaris_threads.h backptr.h hpux_test_and_clear.s $(CORD_SRCS)
 
 OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
            README test.c test_cpp.cc setjmp_t.c SMakefile.amiga \
@@ -180,7 +182,7 @@ OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
            add_gc_prefix.c README.solaris2 README.sgi README.hp README.uts \
           win32_threads.c NT_THREADS_MAKEFILE gc.mak README.dj Makefile.dj \
           README.alpha README.linux version.h Makefile.DLLs \
-          WCC_MAKEFILE nursery.c nursery.h gc_copy_descr.h \
+          WCC_MAKEFILE nursery.c include/gc_nursery.h include/gc_copy_descr.h \
           include/leak_detector.h
 
 CORD_INCLUDE_FILES= $(srcdir)/gc.h $(srcdir)/cord/cord.h $(srcdir)/cord/ec.h \
@@ -242,7 +244,7 @@ gc_cpp.o: $(srcdir)/gc_cpp.cc $(srcdir)/gc_cpp.h $(srcdir)/gc.h Makefile
 test_cpp: $(srcdir)/test_cpp.cc $(srcdir)/gc_cpp.h gc_cpp.o $(srcdir)/gc.h \
 base_lib $(UTILS)
        rm -f test_cpp
-       ./if_mach HP_PA "" $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o gc.a -ldld
+       ./if_mach HP_PA HPUX $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o gc.a -ldld `./threadlibs`
        ./if_not_there test_cpp $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o gc.a `./threadlibs`
 
 c++: gc_cpp.o $(srcdir)/gc_cpp.h test_cpp
@@ -302,9 +304,12 @@ mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ul
        ./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_mach SPARC OPENBSD $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
+       ./if_mach HP_PA HPUX $(AS) -o hpux_test_and_clear.o $(srcdir)/hpux_test_and_clear.s
+       ./if_mach HP_PA HPUX $(CC) -c -o md_tmp.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
+       ./if_mach HP_PA HPUX ld -r -o mach_dep.o md_tmp.o hpux_test_and_clear.o
        ./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)
+mark_rts.o: $(srcdir)/mark_rts.c $(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
@@ -329,13 +334,13 @@ cord/cordprnt.o: $(srcdir)/cord/cordprnt.c $(CORD_INCLUDE_FILES)
 cord/cordtest: $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a $(UTILS)
        rm -f cord/cordtest
        ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a -lucb
-       ./if_mach HP_PA "" $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a -ldld
+       ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a -ldld `./threadlibs`
        ./if_not_there cord/cordtest $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) gc.a `./threadlibs`
 
 cord/de: $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(UTILS)
        rm -f cord/de
        ./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 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 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
@@ -357,16 +362,16 @@ clean:
              threadlibs $(CORD_OBJS) cord/cordtest cord/de
        -rm -f *~
 
-gctest: test.o gc.a if_mach if_not_there
+gctest: test.o gc.a $(UTILS)
        rm -f gctest
        ./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_mach HP_PA HPUX $(CC) $(CFLAGS) -o gctest  test.o gc.a -ldld `./threadlibs`
        ./if_not_there gctest $(CC) $(CFLAGS) -o gctest test.o gc.a `./threadlibs`
 
 # 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: $(srcdir)/setjmp_t.c $(srcdir)/gc.h if_mach if_not_there
+setjmp_test: $(srcdir)/setjmp_t.c $(srcdir)/gc.h $(UTILS)
        $(CC) $(CFLAGS) -o setjmp_test $(srcdir)/setjmp_t.c
 
 test:  KandRtest cord/cordtest
@@ -382,7 +387,7 @@ add_gc_prefix: add_gc_prefix.c
 
 gc.tar: $(SRCS) $(OTHER_FILES) add_gc_prefix
        ./add_gc_prefix $(SRCS) $(OTHER_FILES) > /tmp/gc.tar-files
-       (cd $(srcdir)/.. ; tar cvfh - `cat /tmp/gc.tar-files`) > gc.tar
+       tar cvfh gc.tar `cat /tmp/gc.tar-files`
 
 pc_gc.tar: $(SRCS) $(OTHER_FILES)
        tar cvfX pc_gc.tar pc_excludes $(SRCS) $(OTHER_FILES)
deleted file mode 120000 (symlink)
index 1f801cff3d9bd79d4272aa9729a1297b463dfd43..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-gc.mak
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..0fd22b70d6033132fee18c6936202d6b2bcc151c
--- /dev/null
+# Microsoft Developer Studio Generated NMAKE File, Format Version 4.10
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+!IF "$(CFG)" == ""
+CFG=gctest - Win32 Release
+!MESSAGE No configuration specified.  Defaulting to cord - Win32 Debug.
+!ENDIF 
+
+!IF "$(CFG)" != "gc - Win32 Release" && "$(CFG)" != "gc - Win32 Debug" &&\
+ "$(CFG)" != "gctest - Win32 Release" && "$(CFG)" != "gctest - Win32 Debug" &&\
+ "$(CFG)" != "cord - Win32 Release" && "$(CFG)" != "cord - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line.  For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "gc.mak" CFG="cord - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "gc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "gc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "gctest - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "gctest - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "cord - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "cord - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+!ERROR An invalid configuration is specified.
+!ENDIF 
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE 
+NULL=nul
+!ENDIF 
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "gctest - Win32 Debug"
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : ".\Release\gc.dll" ".\Release\gc.bsc"
+
+CLEAN : 
+       -@erase ".\Release\allchblk.obj"
+       -@erase ".\Release\allchblk.sbr"
+       -@erase ".\Release\alloc.obj"
+       -@erase ".\Release\alloc.sbr"
+       -@erase ".\Release\blacklst.obj"
+       -@erase ".\Release\blacklst.sbr"
+       -@erase ".\Release\checksums.obj"
+       -@erase ".\Release\checksums.sbr"
+       -@erase ".\Release\dbg_mlc.obj"
+       -@erase ".\Release\dbg_mlc.sbr"
+       -@erase ".\Release\dyn_load.obj"
+       -@erase ".\Release\dyn_load.sbr"
+       -@erase ".\Release\finalize.obj"
+       -@erase ".\Release\finalize.sbr"
+       -@erase ".\Release\gc.bsc"
+       -@erase ".\Release\gc.dll"
+       -@erase ".\Release\gc.exp"
+       -@erase ".\Release\gc.lib"
+       -@erase ".\Release\headers.obj"
+       -@erase ".\Release\headers.sbr"
+       -@erase ".\Release\mach_dep.obj"
+       -@erase ".\Release\mach_dep.sbr"
+       -@erase ".\Release\malloc.obj"
+       -@erase ".\Release\malloc.sbr"
+       -@erase ".\Release\mallocx.obj"
+       -@erase ".\Release\mallocx.sbr"
+       -@erase ".\Release\mark.obj"
+       -@erase ".\Release\mark.sbr"
+       -@erase ".\Release\mark_rts.obj"
+       -@erase ".\Release\mark_rts.sbr"
+       -@erase ".\Release\misc.obj"
+       -@erase ".\Release\misc.sbr"
+       -@erase ".\Release\new_hblk.obj"
+       -@erase ".\Release\new_hblk.sbr"
+       -@erase ".\Release\obj_map.obj"
+       -@erase ".\Release\obj_map.sbr"
+       -@erase ".\Release\os_dep.obj"
+       -@erase ".\Release\os_dep.sbr"
+       -@erase ".\Release\ptr_chck.obj"
+       -@erase ".\Release\ptr_chck.sbr"
+       -@erase ".\Release\reclaim.obj"
+       -@erase ".\Release\reclaim.sbr"
+       -@erase ".\Release\stubborn.obj"
+       -@erase ".\Release\stubborn.sbr"
+       -@erase ".\Release\typd_mlc.obj"
+       -@erase ".\Release\typd_mlc.sbr"
+       -@erase ".\Release\win32_threads.obj"
+       -@erase ".\Release\win32_threads.sbr"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
+CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D\
+ "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\
+ "WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\Release/
+CPP_SBRS=.\Release/
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+MTL=mktyplib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32 
+RSC=rc.exe
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/gc.bsc" 
+BSC32_SBRS= \
+       ".\Release\allchblk.sbr" \
+       ".\Release\alloc.sbr" \
+       ".\Release\blacklst.sbr" \
+       ".\Release\checksums.sbr" \
+       ".\Release\dbg_mlc.sbr" \
+       ".\Release\dyn_load.sbr" \
+       ".\Release\finalize.sbr" \
+       ".\Release\headers.sbr" \
+       ".\Release\mach_dep.sbr" \
+       ".\Release\malloc.sbr" \
+       ".\Release\mallocx.sbr" \
+       ".\Release\mark.sbr" \
+       ".\Release\mark_rts.sbr" \
+       ".\Release\misc.sbr" \
+       ".\Release\new_hblk.sbr" \
+       ".\Release\obj_map.sbr" \
+       ".\Release\os_dep.sbr" \
+       ".\Release\ptr_chck.sbr" \
+       ".\Release\reclaim.sbr" \
+       ".\Release\stubborn.sbr" \
+       ".\Release\typd_mlc.sbr" \
+       ".\Release\win32_threads.sbr"
+
+".\Release\gc.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+    $(BSC32) @<<
+  $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
+ /pdb:"$(OUTDIR)/gc.pdb" /machine:I386 /out:"$(OUTDIR)/gc.dll"\
+ /implib:"$(OUTDIR)/gc.lib" 
+LINK32_OBJS= \
+       ".\Release\allchblk.obj" \
+       ".\Release\alloc.obj" \
+       ".\Release\blacklst.obj" \
+       ".\Release\checksums.obj" \
+       ".\Release\dbg_mlc.obj" \
+       ".\Release\dyn_load.obj" \
+       ".\Release\finalize.obj" \
+       ".\Release\headers.obj" \
+       ".\Release\mach_dep.obj" \
+       ".\Release\malloc.obj" \
+       ".\Release\mallocx.obj" \
+       ".\Release\mark.obj" \
+       ".\Release\mark_rts.obj" \
+       ".\Release\misc.obj" \
+       ".\Release\new_hblk.obj" \
+       ".\Release\obj_map.obj" \
+       ".\Release\os_dep.obj" \
+       ".\Release\ptr_chck.obj" \
+       ".\Release\reclaim.obj" \
+       ".\Release\stubborn.obj" \
+       ".\Release\typd_mlc.obj" \
+       ".\Release\win32_threads.obj"
+
+".\Release\gc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+OUTDIR=.\Debug
+INTDIR=.\Debug
+
+ALL : ".\Debug\gc.dll" ".\Debug\gc.bsc"
+
+CLEAN : 
+       -@erase ".\Debug\allchblk.obj"
+       -@erase ".\Debug\allchblk.sbr"
+       -@erase ".\Debug\alloc.obj"
+       -@erase ".\Debug\alloc.sbr"
+       -@erase ".\Debug\blacklst.obj"
+       -@erase ".\Debug\blacklst.sbr"
+       -@erase ".\Debug\checksums.obj"
+       -@erase ".\Debug\checksums.sbr"
+       -@erase ".\Debug\dbg_mlc.obj"
+       -@erase ".\Debug\dbg_mlc.sbr"
+       -@erase ".\Debug\dyn_load.obj"
+       -@erase ".\Debug\dyn_load.sbr"
+       -@erase ".\Debug\finalize.obj"
+       -@erase ".\Debug\finalize.sbr"
+       -@erase ".\Debug\gc.bsc"
+       -@erase ".\Debug\gc.dll"
+       -@erase ".\Debug\gc.exp"
+       -@erase ".\Debug\gc.lib"
+       -@erase ".\Debug\gc.map"
+       -@erase ".\Debug\gc.pdb"
+       -@erase ".\Debug\headers.obj"
+       -@erase ".\Debug\headers.sbr"
+       -@erase ".\Debug\mach_dep.obj"
+       -@erase ".\Debug\mach_dep.sbr"
+       -@erase ".\Debug\malloc.obj"
+       -@erase ".\Debug\malloc.sbr"
+       -@erase ".\Debug\mallocx.obj"
+       -@erase ".\Debug\mallocx.sbr"
+       -@erase ".\Debug\mark.obj"
+       -@erase ".\Debug\mark.sbr"
+       -@erase ".\Debug\mark_rts.obj"
+       -@erase ".\Debug\mark_rts.sbr"
+       -@erase ".\Debug\misc.obj"
+       -@erase ".\Debug\misc.sbr"
+       -@erase ".\Debug\new_hblk.obj"
+       -@erase ".\Debug\new_hblk.sbr"
+       -@erase ".\Debug\obj_map.obj"
+       -@erase ".\Debug\obj_map.sbr"
+       -@erase ".\Debug\os_dep.obj"
+       -@erase ".\Debug\os_dep.sbr"
+       -@erase ".\Debug\ptr_chck.obj"
+       -@erase ".\Debug\ptr_chck.sbr"
+       -@erase ".\Debug\reclaim.obj"
+       -@erase ".\Debug\reclaim.sbr"
+       -@erase ".\Debug\stubborn.obj"
+       -@erase ".\Debug\stubborn.sbr"
+       -@erase ".\Debug\typd_mlc.obj"
+       -@erase ".\Debug\typd_mlc.sbr"
+       -@erase ".\Debug\vc40.idb"
+       -@erase ".\Debug\vc40.pdb"
+       -@erase ".\Debug\win32_threads.obj"
+       -@erase ".\Debug\win32_threads.sbr"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "SILENT" /D "GC_BUILD"\
+ /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\
+ "WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\
+ /Fd"$(INTDIR)/" /c 
+CPP_OBJS=.\Debug/
+CPP_SBRS=.\Debug/
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+MTL=mktyplib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32 
+RSC=rc.exe
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/gc.bsc" 
+BSC32_SBRS= \
+       ".\Debug\allchblk.sbr" \
+       ".\Debug\alloc.sbr" \
+       ".\Debug\blacklst.sbr" \
+       ".\Debug\checksums.sbr" \
+       ".\Debug\dbg_mlc.sbr" \
+       ".\Debug\dyn_load.sbr" \
+       ".\Debug\finalize.sbr" \
+       ".\Debug\headers.sbr" \
+       ".\Debug\mach_dep.sbr" \
+       ".\Debug\malloc.sbr" \
+       ".\Debug\mallocx.sbr" \
+       ".\Debug\mark.sbr" \
+       ".\Debug\mark_rts.sbr" \
+       ".\Debug\misc.sbr" \
+       ".\Debug\new_hblk.sbr" \
+       ".\Debug\obj_map.sbr" \
+       ".\Debug\os_dep.sbr" \
+       ".\Debug\ptr_chck.sbr" \
+       ".\Debug\reclaim.sbr" \
+       ".\Debug\stubborn.sbr" \
+       ".\Debug\typd_mlc.sbr" \
+       ".\Debug\win32_threads.sbr"
+
+".\Debug\gc.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+    $(BSC32) @<<
+  $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
+ /pdb:"$(OUTDIR)/gc.pdb" /map:"$(INTDIR)/gc.map" /debug /machine:I386\
+ /out:"$(OUTDIR)/gc.dll" /implib:"$(OUTDIR)/gc.lib" 
+LINK32_OBJS= \
+       ".\Debug\allchblk.obj" \
+       ".\Debug\alloc.obj" \
+       ".\Debug\blacklst.obj" \
+       ".\Debug\checksums.obj" \
+       ".\Debug\dbg_mlc.obj" \
+       ".\Debug\dyn_load.obj" \
+       ".\Debug\finalize.obj" \
+       ".\Debug\headers.obj" \
+       ".\Debug\mach_dep.obj" \
+       ".\Debug\malloc.obj" \
+       ".\Debug\mallocx.obj" \
+       ".\Debug\mark.obj" \
+       ".\Debug\mark_rts.obj" \
+       ".\Debug\misc.obj" \
+       ".\Debug\new_hblk.obj" \
+       ".\Debug\obj_map.obj" \
+       ".\Debug\os_dep.obj" \
+       ".\Debug\ptr_chck.obj" \
+       ".\Debug\reclaim.obj" \
+       ".\Debug\stubborn.obj" \
+       ".\Debug\typd_mlc.obj" \
+       ".\Debug\win32_threads.obj"
+
+".\Debug\gc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "gctest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "gctest\Release"
+# PROP BASE Intermediate_Dir "gctest\Release"
+# PROP BASE Target_Dir "gctest"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "gctest\Release"
+# PROP Intermediate_Dir "gctest\Release"
+# PROP Target_Dir "gctest"
+OUTDIR=.\gctest\Release
+INTDIR=.\gctest\Release
+
+ALL : "gc - Win32 Release" ".\Release\gctest.exe"
+
+CLEAN : 
+       -@erase ".\gctest\Release\test.obj"
+       -@erase ".\Release\gctest.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /YX /c
+CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS"\
+ /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\gctest\Release/
+CPP_SBRS=.\.
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+MTL=mktyplib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32 
+RSC=rc.exe
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/gctest.bsc" 
+BSC32_SBRS= \
+       
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/gctest.exe"
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/gctest.pdb" /machine:I386 /out:"Release/gctest.exe" 
+LINK32_OBJS= \
+       ".\gctest\Release\test.obj" \
+       ".\Release\gc.lib"
+
+".\Release\gctest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "gctest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "gctest\Debug"
+# PROP BASE Intermediate_Dir "gctest\Debug"
+# PROP BASE Target_Dir "gctest"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "gctest\Debug"
+# PROP Intermediate_Dir "gctest\Debug"
+# PROP Target_Dir "gctest"
+OUTDIR=.\gctest\Debug
+INTDIR=.\gctest\Debug
+
+ALL : "gc - Win32 Debug" ".\Debug\gctest.exe" ".\gctest\Debug\gctest.bsc"
+
+CLEAN : 
+       -@erase ".\Debug\gctest.exe"
+       -@erase ".\gctest\Debug\gctest.bsc"
+       -@erase ".\gctest\Debug\gctest.map"
+       -@erase ".\gctest\Debug\gctest.pdb"
+       -@erase ".\gctest\Debug\test.obj"
+       -@erase ".\gctest\Debug\test.sbr"
+       -@erase ".\gctest\Debug\vc40.idb"
+       -@erase ".\gctest\Debug\vc40.pdb"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
+ /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR"$(INTDIR)/"\
+ /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c 
+CPP_OBJS=.\gctest\Debug/
+CPP_SBRS=.\gctest\Debug/
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+MTL=mktyplib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32 
+RSC=rc.exe
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/gctest.bsc" 
+BSC32_SBRS= \
+       ".\gctest\Debug\test.sbr"
+
+".\gctest\Debug\gctest.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+    $(BSC32) @<<
+  $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no /map /debug /machine:I386 /out:"Debug/gctest.exe"
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/gctest.pdb" /map:"$(INTDIR)/gctest.map" /debug /machine:I386\
+ /out:"Debug/gctest.exe" 
+LINK32_OBJS= \
+       ".\Debug\gc.lib" \
+       ".\gctest\Debug\test.obj"
+
+".\Debug\gctest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "cord\Release"
+# PROP BASE Intermediate_Dir "cord\Release"
+# PROP BASE Target_Dir "cord"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "cord\Release"
+# PROP Intermediate_Dir "cord\Release"
+# PROP Target_Dir "cord"
+OUTDIR=.\cord\Release
+INTDIR=.\cord\Release
+
+ALL : "gc - Win32 Release" ".\Release\de.exe"
+
+CLEAN : 
+       -@erase ".\cord\Release\cordbscs.obj"
+       -@erase ".\cord\Release\cordxtra.obj"
+       -@erase ".\cord\Release\de.obj"
+       -@erase ".\cord\Release\de_win.obj"
+       -@erase ".\cord\Release\de_win.res"
+       -@erase ".\Release\de.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /YX /c
+CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "ALL_INTERIOR_POINTERS" /Fp"$(INTDIR)/cord.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\cord\Release/
+CPP_SBRS=.\.
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+MTL=mktyplib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32 
+RSC=rc.exe
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+RSC_PROJ=/l 0x809 /fo"$(INTDIR)/de_win.res" /d "NDEBUG" 
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/cord.bsc" 
+BSC32_SBRS= \
+       
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/de.exe"
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)/de.pdb"\
+ /machine:I386 /out:"Release/de.exe" 
+LINK32_OBJS= \
+       ".\cord\Release\cordbscs.obj" \
+       ".\cord\Release\cordxtra.obj" \
+       ".\cord\Release\de.obj" \
+       ".\cord\Release\de_win.obj" \
+       ".\cord\Release\de_win.res" \
+       ".\Release\gc.lib"
+
+".\Release\de.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "cord\Debug"
+# PROP BASE Intermediate_Dir "cord\Debug"
+# PROP BASE Target_Dir "cord"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "cord\Debug"
+# PROP Intermediate_Dir "cord\Debug"
+# PROP Target_Dir "cord"
+OUTDIR=.\cord\Debug
+INTDIR=.\cord\Debug
+
+ALL : "gc - Win32 Debug" ".\Debug\de.exe"
+
+CLEAN : 
+       -@erase ".\cord\Debug\cordbscs.obj"
+       -@erase ".\cord\Debug\cordxtra.obj"
+       -@erase ".\cord\Debug\de.obj"
+       -@erase ".\cord\Debug\de.pdb"
+       -@erase ".\cord\Debug\de_win.obj"
+       -@erase ".\cord\Debug\de_win.res"
+       -@erase ".\cord\Debug\vc40.idb"
+       -@erase ".\cord\Debug\vc40.pdb"
+       -@erase ".\Debug\de.exe"
+       -@erase ".\Debug\de.ilk"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /YX /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "." /D "_DEBUG" /D "WIN32" /D\
+ "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /Fp"$(INTDIR)/cord.pch" /YX\
+ /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c 
+CPP_OBJS=.\cord\Debug/
+CPP_SBRS=.\.
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+MTL=mktyplib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32 
+RSC=rc.exe
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+RSC_PROJ=/l 0x809 /fo"$(INTDIR)/de_win.res" /d "_DEBUG" 
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/cord.bsc" 
+BSC32_SBRS= \
+       
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/de.exe"
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /incremental:yes\
+ /pdb:"$(OUTDIR)/de.pdb" /debug /machine:I386 /out:"Debug/de.exe" 
+LINK32_OBJS= \
+       ".\cord\Debug\cordbscs.obj" \
+       ".\cord\Debug\cordxtra.obj" \
+       ".\cord\Debug\de.obj" \
+       ".\cord\Debug\de_win.obj" \
+       ".\cord\Debug\de_win.res" \
+       ".\Debug\gc.lib"
+
+".\Debug\de.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF 
+
+################################################################################
+# Begin Target
+
+# Name "gc - Win32 Release"
+# Name "gc - Win32 Debug"
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\reclaim.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_RECLA=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_RECLA=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\reclaim.obj" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)"
+
+".\Release\reclaim.sbr" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_RECLA=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_RECLA=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\reclaim.obj" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)"
+
+".\Debug\reclaim.sbr" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\os_dep.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_OS_DE=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\STAT.H"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_OS_DE=\
+       ".\il\PCR_IL.h"\
+       ".\mm\PCR_MM.h"\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       ".\vd\PCR_VD.h"\
+       
+
+".\Release\os_dep.obj" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)"
+
+".\Release\os_dep.sbr" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_OS_DE=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\STAT.H"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_OS_DE=\
+       ".\il\PCR_IL.h"\
+       ".\mm\PCR_MM.h"\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       ".\vd\PCR_VD.h"\
+       
+
+".\Debug\os_dep.obj" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)"
+
+".\Debug\os_dep.sbr" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\misc.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_MISC_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MISC_=\
+       ".\il\PCR_IL.h"\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\misc.obj" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)"
+
+".\Release\misc.sbr" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_MISC_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MISC_=\
+       ".\il\PCR_IL.h"\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\misc.obj" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)"
+
+".\Debug\misc.sbr" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\mark_rts.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_MARK_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MARK_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\mark_rts.obj" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)"
+
+".\Release\mark_rts.sbr" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_MARK_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MARK_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\mark_rts.obj" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)"
+
+".\Debug\mark_rts.sbr" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\mach_dep.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_MACH_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MACH_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\mach_dep.obj" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)"
+
+".\Release\mach_dep.sbr" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_MACH_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MACH_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\mach_dep.obj" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)"
+
+".\Debug\mach_dep.sbr" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\headers.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_HEADE=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_HEADE=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\headers.obj" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)"
+
+".\Release\headers.sbr" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_HEADE=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_HEADE=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\headers.obj" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)"
+
+".\Debug\headers.sbr" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\alloc.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_ALLOC=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_ALLOC=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\alloc.obj" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)"
+
+".\Release\alloc.sbr" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_ALLOC=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_ALLOC=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\alloc.obj" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)"
+
+".\Debug\alloc.sbr" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\allchblk.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_ALLCH=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_ALLCH=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\allchblk.obj" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)"
+
+".\Release\allchblk.sbr" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_ALLCH=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_ALLCH=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\allchblk.obj" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)"
+
+".\Debug\allchblk.sbr" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\stubborn.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_STUBB=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_STUBB=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\stubborn.obj" : $(SOURCE) $(DEP_CPP_STUBB) "$(INTDIR)"
+
+".\Release\stubborn.sbr" : $(SOURCE) $(DEP_CPP_STUBB) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_STUBB=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_STUBB=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\stubborn.obj" : $(SOURCE) $(DEP_CPP_STUBB) "$(INTDIR)"
+
+".\Debug\stubborn.sbr" : $(SOURCE) $(DEP_CPP_STUBB) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\obj_map.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_OBJ_M=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_OBJ_M=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\obj_map.obj" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)"
+
+".\Release\obj_map.sbr" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_OBJ_M=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_OBJ_M=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\obj_map.obj" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)"
+
+".\Debug\obj_map.sbr" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\new_hblk.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_NEW_H=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_NEW_H=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\new_hblk.obj" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)"
+
+".\Release\new_hblk.sbr" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_NEW_H=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_NEW_H=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\new_hblk.obj" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)"
+
+".\Debug\new_hblk.sbr" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\mark.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_MARK_C=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MARK_C=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\mark.obj" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)"
+
+".\Release\mark.sbr" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_MARK_C=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MARK_C=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\mark.obj" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)"
+
+".\Debug\mark.sbr" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\malloc.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_MALLO=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MALLO=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\malloc.obj" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)"
+
+".\Release\malloc.sbr" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_MALLO=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MALLO=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\malloc.obj" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)"
+
+".\Debug\malloc.sbr" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\mallocx.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_MALLX=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MALLX=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\mallocx.obj" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)"
+
+".\Release\mallocx.sbr" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_MALLX=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_MALLX=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\mallocx.obj" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)"
+
+".\Debug\mallocx.sbr" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\finalize.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_FINAL=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_FINAL=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\finalize.obj" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)"
+
+".\Release\finalize.sbr" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_FINAL=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_FINAL=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\finalize.obj" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)"
+
+".\Debug\finalize.sbr" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\dbg_mlc.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_DBG_M=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_DBG_M=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\dbg_mlc.obj" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)"
+
+".\Release\dbg_mlc.sbr" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_DBG_M=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_DBG_M=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\dbg_mlc.obj" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)"
+
+".\Debug\dbg_mlc.sbr" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\blacklst.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_BLACK=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_BLACK=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\blacklst.obj" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)"
+
+".\Release\blacklst.sbr" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_BLACK=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_BLACK=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\blacklst.obj" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)"
+
+".\Debug\blacklst.sbr" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\typd_mlc.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_TYPD_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       ".\gc_typed.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_TYPD_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\typd_mlc.obj" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)"
+
+".\Release\typd_mlc.sbr" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_TYPD_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       ".\gc_typed.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_TYPD_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\typd_mlc.obj" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)"
+
+".\Debug\typd_mlc.sbr" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\ptr_chck.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_PTR_C=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_PTR_C=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\ptr_chck.obj" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)"
+
+".\Release\ptr_chck.sbr" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_PTR_C=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_mark.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_PTR_C=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\ptr_chck.obj" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)"
+
+".\Debug\ptr_chck.sbr" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\dyn_load.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_DYN_L=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\STAT.H"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_DYN_L=\
+       ".\il\PCR_IL.h"\
+       ".\mm\PCR_MM.h"\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\dyn_load.obj" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)"
+
+".\Release\dyn_load.sbr" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_DYN_L=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\STAT.H"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_DYN_L=\
+       ".\il\PCR_IL.h"\
+       ".\mm\PCR_MM.h"\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\dyn_load.obj" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)"
+
+".\Debug\dyn_load.sbr" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\win32_threads.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_WIN32=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_WIN32=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\win32_threads.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+
+".\Release\win32_threads.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_WIN32=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_WIN32=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\win32_threads.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+
+".\Debug\win32_threads.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\checksums.c
+
+!IF  "$(CFG)" == "gc - Win32 Release"
+
+DEP_CPP_CHECK=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_CHECK=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Release\checksums.obj" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)"
+
+".\Release\checksums.sbr" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gc - Win32 Debug"
+
+DEP_CPP_CHECK=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_CHECK=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+".\Debug\checksums.obj" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)"
+
+".\Debug\checksums.sbr" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "gctest - Win32 Release"
+# Name "gctest - Win32 Debug"
+
+!IF  "$(CFG)" == "gctest - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "gctest - Win32 Debug"
+
+!ENDIF 
+
+################################################################################
+# Begin Project Dependency
+
+# Project_Dep_Name "gc"
+
+!IF  "$(CFG)" == "gctest - Win32 Release"
+
+"gc - Win32 Release" : 
+   $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Release" 
+
+!ELSEIF  "$(CFG)" == "gctest - Win32 Debug"
+
+"gc - Win32 Debug" : 
+   $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Debug" 
+
+!ENDIF 
+
+# End Project Dependency
+################################################################################
+# Begin Source File
+
+SOURCE=.\test.c
+DEP_CPP_TEST_=\
+       ".\gcconfig.h"\
+       ".\gc.h"\
+       ".\gc_hdrs.h"\
+       ".\gc_priv.h"\
+       ".\gc_typed.h"\
+       {$(INCLUDE)}"\sys\TYPES.H"\
+       
+NODEP_CPP_TEST_=\
+       ".\th\PCR_Th.h"\
+       ".\th\PCR_ThCrSec.h"\
+       ".\th\PCR_ThCtl.h"\
+       
+
+!IF  "$(CFG)" == "gctest - Win32 Release"
+
+
+".\gctest\Release\test.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "gctest - Win32 Debug"
+
+
+".\gctest\Debug\test.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
+
+".\gctest\Debug\test.sbr" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
+
+
+!ENDIF 
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "cord - Win32 Release"
+# Name "cord - Win32 Debug"
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+!ENDIF 
+
+################################################################################
+# Begin Project Dependency
+
+# Project_Dep_Name "gc"
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+"gc - Win32 Release" : 
+   $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Release" 
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+"gc - Win32 Debug" : 
+   $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Debug" 
+
+!ENDIF 
+
+# End Project Dependency
+################################################################################
+# Begin Source File
+
+SOURCE=.\cord\de_win.c
+DEP_CPP_DE_WI=\
+       ".\cord\cord.h"\
+       ".\cord\de_cmds.h"\
+       ".\cord\de_win.h"\
+       ".\cord\private\cord_pos.h"\
+       
+NODEP_CPP_DE_WI=\
+       ".\cord\gc.h"\
+       
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+
+".\cord\Release\de_win.obj" : $(SOURCE) $(DEP_CPP_DE_WI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+
+".\cord\Debug\de_win.obj" : $(SOURCE) $(DEP_CPP_DE_WI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\cord\de.c
+DEP_CPP_DE_C2e=\
+       ".\cord\cord.h"\
+       ".\cord\de_cmds.h"\
+       ".\cord\de_win.h"\
+       ".\cord\private\cord_pos.h"\
+       
+NODEP_CPP_DE_C2e=\
+       ".\cord\gc.h"\
+       
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+
+".\cord\Release\de.obj" : $(SOURCE) $(DEP_CPP_DE_C2e) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+
+".\cord\Debug\de.obj" : $(SOURCE) $(DEP_CPP_DE_C2e) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\cord\cordxtra.c
+DEP_CPP_CORDX=\
+       ".\cord\cord.h"\
+       ".\cord\ec.h"\
+       ".\cord\private\cord_pos.h"\
+       
+NODEP_CPP_CORDX=\
+       ".\cord\gc.h"\
+       
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+
+".\cord\Release\cordxtra.obj" : $(SOURCE) $(DEP_CPP_CORDX) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+
+".\cord\Debug\cordxtra.obj" : $(SOURCE) $(DEP_CPP_CORDX) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\cord\cordbscs.c
+DEP_CPP_CORDB=\
+       ".\cord\cord.h"\
+       ".\cord\private\cord_pos.h"\
+       
+NODEP_CPP_CORDB=\
+       ".\cord\gc.h"\
+       
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+
+".\cord\Release\cordbscs.obj" : $(SOURCE) $(DEP_CPP_CORDB) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+
+".\cord\Debug\cordbscs.obj" : $(SOURCE) $(DEP_CPP_CORDB) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF 
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\cord\de_win.RC
+
+!IF  "$(CFG)" == "cord - Win32 Release"
+
+
+".\cord\Release\de_win.res" : $(SOURCE) "$(INTDIR)"
+   $(RSC) /l 0x809 /fo"$(INTDIR)/de_win.res" /i "cord" /d "NDEBUG" $(SOURCE)
+
+
+!ELSEIF  "$(CFG)" == "cord - Win32 Debug"
+
+
+".\cord\Debug\de_win.res" : $(SOURCE) "$(INTDIR)"
+   $(RSC) /l 0x809 /fo"$(INTDIR)/de_win.res" /i "cord" /d "_DEBUG" $(SOURCE)
+
+
+!ENDIF 
+
+# End Source File
+# End Target
+# End Project
+################################################################################
diff --git a/README b/README
index 80cb26ab4b1dfa9094b9dabb414aff0fdda59e91..957ddbaf161db1a549692529b980ac76730c7302 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,7 @@
 Copyright 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 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.
@@ -11,7 +12,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 5.0alpha3 of a conservative garbage collector for C and C++.
+This is version 5.0alpha4 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
@@ -1497,6 +1498,32 @@ Since 5.0alpha2
  - Significantly changed the way leak detection is handled, as a consequence
    of the above.
 
+Since 5.0 alpha3
+ - Added protection fault handling patch for Linux/M68K from Fergus
+   Henderson and Roman Hodek.
+ - Removed the tests for SGI_SOURCE in new_gc_alloc.h.  This was causing that
+   interface to fail on nonSGI platforms.
+ - Changed the Linux stack finding code to use /proc, after chnging it
+   to use HEURISTIC1.  (Thanks to David Mossberger for pointing out the
+   /proc hook.)
+ - Added HP/UX incremental GC support and HP/UX 11 thread support.
+ - Added basic Linux/IA64 support.
+ - Integrated Anthony Green's PicoJava support.
+ - Integrated Scott Ananian's StrongARM/NetBSD support.
+ - Fixed some fairly serious performance bugs in the incremental
+   collector.  These have probably been there essentially forever.
+   (Mark bits were sometimes set before scanning dirty pages.
+   The reclaim phase unnecessarily dirtied full small object pages.)
+ - Changed the reclaim phase to ignore nearly full pages to avoid
+   touching them.
+ - Limited GC_black_list_spacing to roughly the heap growth increment.
+ - Changed full collection triggering heuristic to decrease full GC
+   frequency by default, but to explicitly trigger full GCs during
+   heap growth.  This doesn't always improve things, but on average it's
+   probably a win.
+ - GC_debug_free(0, ...) failed.  Thanks to Fergus Henderson for the
+   bug report and fix.
+
 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
@@ -1510,8 +1537,6 @@ To do:
    be possible to conditionally intercept mmap and use GC_exclude_static_roots.
    The real fix is to walk rld data structures, which looks possible.
  - Integrate MIT and DEC pthreads ports.
- - Deal with very uneven black-listing distributions.  If all the black listed
-   blocks reside in the newly allocated heap section, the heuristic for
-   temporarily ignoring black-listing fails, and the heap grows too much.
-   (This was observed in only one case, and could be worked around, but ...)
- - Some platform specific updates are waiting for 4.15alpha1. 
+ - Incremental collector should handle large objects better.  Currently,
+   it looks like the whole object is treated as dirty if any part of it
+   is.
index 3273c8ba4ebcddc82a670c48ebb498b170689b8c..ddebf82ca50b7cb3b9b4baa31f4f5d37d887418d 100644 (file)
@@ -1,5 +1,7 @@
 Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
-Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
+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. All rights reserved.
 
 THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
index b290590d13b07425a3144948e069a82c7da02aa9..072ba5386ac9895e01b8086c5acb921f9ebb03bb 100644 (file)
--- a/README.hp
+++ b/README.hp
@@ -8,4 +8,9 @@ The collector should compile with either plain cc or cc -Ae.  CC -Aa
 fails to define _HPUX_SOURCE and thus will not configure the collector
 correctly.
 
-There is currently no thread support.
+Incremental collection support was reccently added, and should now work.
+
+Thread support for HP/UX 11 Pthreads was also recently added.  It is still
+flakey in this release.  (It has only been tested on a uniprocessor.  Even
+there some fraction of thread creation calls fail with a not-yet-understood
+error return from sem_wait.)
index d8d0afdf570907863e118d45d14ab33e1f8fcd13..189b94214a7376ff4f89110723199d92b7b2a0a4 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  * Copyright (c) 1998-1999 by Silicon Graphics.  All rights reserved.
+ * Copyright (c) 1999 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.
@@ -122,7 +123,7 @@ hdr * wanted;
 
 void GC_dump_regions()
 {
-    int i;
+    unsigned i;
     ptr_t start, end;
     ptr_t p;
     size_t bytes;
diff --git a/alloc.c b/alloc.c
index 1c57951f9014817c84b97f9b0b30df604fc6eddb..65bb602b22e5474a31373c9f9cc4350b42bb55e5 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -1,7 +1,8 @@
 /*
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
- * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
+ * Copyright (c) 1991-1996 by Xerox Corporation.  All rights reserved.
  * Copyright (c) 1998 by Silicon Graphics.  All rights reserved.
+ * Copyright (c) 1999 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.
@@ -62,8 +63,16 @@ word GC_gc_no = 0;
   int GC_incremental = 0;    /* By default, stop the world.    */
 #endif
 
-int GC_full_freq = 4;     /* Every 5th collection is a full    */
-                          /* collection.                       */
+int GC_full_freq = 19;    /* Every 20th collection is a full   */
+                          /* collection, whether we need it    */
+                          /* or not.                           */
+
+GC_bool GC_need_full_gc = FALSE;
+                          /* Need full GC do to heap growth.   */
+
+#define USED_HEAP_SIZE (GC_heapsize - GC_large_free_bytes)
+
+word GC_used_heap_size_after_full = 0;
 
 char * GC_copyright[] =
 {"Copyright 1988,1989 Hans-J. Boehm and Alan J. Demers ",
@@ -210,6 +219,7 @@ GC_bool GC_should_collect()
     return(GC_adj_words_allocd() >= min_words_allocd());
 }
 
+
 void GC_notify_full_gc()
 {
     if (GC_start_call_back != (void (*)())0) {
@@ -217,6 +227,8 @@ void GC_notify_full_gc()
     }
 }
 
+GC_bool GC_is_full_gc = FALSE;
+
 /* 
  * Initiate a garbage collection if appropriate.
  * Choose judiciously
@@ -226,7 +238,6 @@ void GC_notify_full_gc()
 void GC_maybe_gc()
 {
     static int n_partial_gcs = 0;
-    GC_bool is_full_gc = FALSE;
 
     if (GC_should_collect()) {
         if (!GC_incremental) {
@@ -234,7 +245,7 @@ void GC_maybe_gc()
             GC_gcollect_inner();
             n_partial_gcs = 0;
             return;
-        } else if (n_partial_gcs >= GC_full_freq) {
+        } else if (GC_need_full_gc || n_partial_gcs >= GC_full_freq) {
 #          ifdef PRINTSTATS
              GC_printf2(
                "***>Full mark for collection %lu after %ld allocd bytes\n",
@@ -246,7 +257,7 @@ void GC_maybe_gc()
            GC_clear_marks();
             n_partial_gcs = 0;
            GC_notify_full_gc();
-           is_full_gc = TRUE;
+           GC_is_full_gc = TRUE;
         } else {
             n_partial_gcs++;
         }
@@ -260,7 +271,7 @@ void GC_maybe_gc()
 #           endif
             GC_finish_collection();
         } else {
-           if (!is_full_gc) {
+           if (!GC_is_full_gc) {
                /* Count this as the first attempt */
                GC_n_attempts++;
            }
@@ -307,6 +318,7 @@ GC_stop_func stop_func;
 #   ifdef SAVE_CALL_CHAIN
         GC_save_callers(GC_last_stack);
 #   endif
+    GC_is_full_gc = TRUE;
     if (!GC_stopped_mark(stop_func)) {
       if (!GC_incremental) {
        /* We're partially done and have no way to complete or use      */
@@ -548,6 +560,14 @@ void GC_finish_collection()
 #   endif
     /* Reconstruct free lists to contain everything not marked */
         GC_start_reclaim(FALSE);
+        if (GC_is_full_gc)  {
+           GC_used_heap_size_after_full = USED_HEAP_SIZE;
+           GC_need_full_gc = FALSE;
+       } else {
+           GC_need_full_gc =
+                BYTES_TO_WORDS(USED_HEAP_SIZE - GC_used_heap_size_after_full)
+                > min_words_allocd();
+       }
 
 #   ifdef PRINTSTATS
        GC_printf2(
@@ -564,6 +584,7 @@ void GC_finish_collection()
 #   endif
 
       GC_n_attempts = 0;
+      GC_is_full_gc = FALSE;
     /* Reset or increment counters for next cycle */
       GC_words_allocd_before_gc += GC_words_allocd;
       GC_non_gc_bytes_at_gc = GC_non_gc_bytes;
index 0d623c0fcf622e7f3b27a26a7d4d7b5d8ed79886..e5a3a26a8cfa4ba716577ccc00f85cd3e3571b99 100644 (file)
@@ -145,6 +145,13 @@ void GC_promote_black_lists()
     if (GC_black_list_spacing < 3 * HBLKSIZE) {
        GC_black_list_spacing = 3 * HBLKSIZE;
     }
+    if (GC_black_list_spacing > MAXHINCR * HBLKSIZE) {
+       GC_black_list_spacing = MAXHINCR * HBLKSIZE;
+       /* Makes it easier to allocate really huge blocks, which otherwise */
+       /* may have problems with nonuniform blacklist distributions.      */
+       /* This way we should always succeed immediately after growing the */ 
+       /* heap.                                                           */
+    }
 }
 
 void GC_unpromote_black_lists()
index 584112fd181089b8e61449db6fa02ca34f9157ad..926089e86fbb18567aa48981aa68dc152f1e7b76 100644 (file)
@@ -41,7 +41,7 @@
  * This interface is fairly big, largely for performance reasons.
  * The most basic constants and functions:
  *
- * CORD - the type fo a cord;
+ * CORD - the type of a cord;
  * CORD_EMPTY - empty cord;
  * CORD_len(cord) - length of a cord;
  * CORD_cat(cord1,cord2) - concatenation of two cords;
index 306140953140520f39ab5e3064e588b968e9aa78..cc74765d098ef28993593971faef5d5105cefe2f 100644 (file)
--- a/cord/gc.h
+++ b/cord/gc.h
 # if defined(__STDC__) || defined(__cplusplus)
 #   define GC_PROTO(args) args
     typedef void * GC_PTR;
+#   define GC_CONST const
 # else
 #   define GC_PROTO(args) ()
     typedef char * GC_PTR;
+#   define GC_CONST
 #  endif
 
 # ifdef __cplusplus
@@ -131,6 +133,12 @@ GC_API int GC_dont_expand;
 GC_API int GC_full_freq;    /* Number of partial collections between   */
                            /* full collections.  Matters only if       */
                            /* GC_incremental is set.                   */
+                           /* Full collections are also triggered if   */
+                           /* the collector detects a substantial      */
+                           /* increase in the number of in-use heap    */
+                           /* blocks.  Values in the tens are now      */
+                           /* perfectly reasonable, unlike for         */
+                           /* earlier GC versions.                     */
                        
 GC_API GC_word GC_non_gc_bytes;
                        /* Bytes not considered candidates for collection. */
@@ -297,6 +305,9 @@ GC_API int GC_try_to_collect GC_PROTO((GC_stop_func stop_func));
 /* Includes some pages that were allocated but never written.          */
 GC_API size_t GC_get_heap_size GC_PROTO((void));
 
+/* Return a lower bound on the number of free bytes in the heap.       */
+GC_API size_t GC_get_free_bytes GC_PROTO((void));
+
 /* Return the number of bytes allocated since the last collection.     */
 GC_API size_t GC_get_bytes_since_gc GC_PROTO((void));
 
@@ -341,10 +352,11 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
 
 #ifdef GC_ADD_CALLER
 #  define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
-#  define GC_EXTRA_PARAMS GC_word ra, char * descr_string, int descr_int
+#  define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * descr_string,
+                         int descr_int
 #else
 #  define GC_EXTRAS __FILE__, __LINE__
-#  define GC_EXTRA_PARAMS char * descr_string, int descr_int
+#  define GC_EXTRA_PARAMS GC_CONST char * descr_string, int descr_int
 #endif
 
 /* Debugging (annotated) allocation.  GC_gcollect will check           */
@@ -688,7 +700,7 @@ GC_API void (*GC_is_visible_print_proc)
 # endif /* SOLARIS_THREADS */
 
 
-#if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
 /* We treat these similarly. */
 # include <pthread.h>
 # include <signal.h>
@@ -707,7 +719,7 @@ GC_API void (*GC_is_visible_print_proc)
 
 # if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \
        defined(IRIX_THREADS) || defined(LINUX_THREADS) || \
-       defined(IRIX_JDK_THREADS)
+       defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
        /* Any flavor of threads except SRC_M3. */
 /* This returns a list of objects, linked through their first          */
 /* word.  Its use can greatly reduce lock contention problems, since   */
index 648325676351e566945f6ab252dcc344a929de2d..41843be1fa0dbc0d79925122f5c366ef03e57ce0 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -343,10 +343,10 @@ void GC_start_debugging()
 }
 
 # ifdef GC_ADD_CALLER
-#   define EXTRA_ARGS word ra, char * s, int i
+#   define EXTRA_ARGS word ra, CONST char * s, int i
 #   define OPT_RA ra,
 # else
-#   define EXTRA_ARGS char * s, int i
+#   define EXTRA_ARGS CONST char * s, int i
 #   define OPT_RA
 # endif
 
@@ -531,13 +531,15 @@ GC_PTR p;
     GC_PTR p;
 # endif
 {
-    register GC_PTR base = GC_base(p);
+    register GC_PTR base;
     register ptr_t clobbered;
     
+    if (0 == p) return;
+    base = GC_base(p);
     if (base == 0) {
         GC_err_printf1("Attempt to free invalid pointer %lx\n",
                       (unsigned long)p);
-        if (p != 0) ABORT("free(invalid pointer)");
+        ABORT("free(invalid pointer)");
     }
     if ((ptr_t)p - (ptr_t)base != sizeof(oh)) {
         GC_err_printf1(
index d3df0a0821f490b9df09c025ec50f750b85c8ddd..8c3ec4186c40c6c7b37338b2f88c57f68c348a08 100644 (file)
@@ -47,7 +47,7 @@
 #if (defined(DYNAMIC_LOADING) || defined(MSWIN32)) && !defined(PCR)
 #if !defined(SUNOS4) && !defined(SUNOS5DL) && !defined(IRIX5) && \
     !defined(MSWIN32) && !(defined(ALPHA) && defined(OSF1)) && \
-    !defined(HP_PA) && !(defined(LINUX) && defined(__ELF__)) && \
+    !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
     !defined(RS6000) && !defined(SCO_ELF)
  --> We only know how to find data segments of dynamic libraries for the
  --> above.  Additional SVR4 variants might not be too
@@ -658,7 +658,7 @@ void GC_register_dynamic_libraries()
 }
 #endif
 
-#if defined(HP_PA)
+#if defined(HPUX)
 
 #include <errno.h>
 #include <dl.h>
@@ -681,6 +681,11 @@ void GC_register_dynamic_libraries()
 
       /* Check if this is the end of the list or if some error occured */
         if (status != 0) {
+#       ifdef HPUX_THREADS
+          /* I've seen errno values of 0.  The man page is not clear   */
+          /* as to whether errno should get set on a -1 return.        */
+          break;
+#       else
           if (errno == EINVAL) {
               break; /* Moved past end of shared library list --> finished */
           } else {
@@ -691,6 +696,7 @@ void GC_register_dynamic_libraries()
              }
               ABORT("shl_get failed");
           }
+#       endif
         }
 
 #     ifdef VERBOSE
@@ -713,7 +719,7 @@ void GC_register_dynamic_libraries()
         index++;
     }
 }
-#endif /* HP_PA */
+#endif /* HPUX */
 
 #ifdef RS6000
 #pragma alloca
diff --git a/gc.h b/gc.h
index 306140953140520f39ab5e3064e588b968e9aa78..cc74765d098ef28993593971faef5d5105cefe2f 100644 (file)
--- a/gc.h
+++ b/gc.h
 # if defined(__STDC__) || defined(__cplusplus)
 #   define GC_PROTO(args) args
     typedef void * GC_PTR;
+#   define GC_CONST const
 # else
 #   define GC_PROTO(args) ()
     typedef char * GC_PTR;
+#   define GC_CONST
 #  endif
 
 # ifdef __cplusplus
@@ -131,6 +133,12 @@ GC_API int GC_dont_expand;
 GC_API int GC_full_freq;    /* Number of partial collections between   */
                            /* full collections.  Matters only if       */
                            /* GC_incremental is set.                   */
+                           /* Full collections are also triggered if   */
+                           /* the collector detects a substantial      */
+                           /* increase in the number of in-use heap    */
+                           /* blocks.  Values in the tens are now      */
+                           /* perfectly reasonable, unlike for         */
+                           /* earlier GC versions.                     */
                        
 GC_API GC_word GC_non_gc_bytes;
                        /* Bytes not considered candidates for collection. */
@@ -297,6 +305,9 @@ GC_API int GC_try_to_collect GC_PROTO((GC_stop_func stop_func));
 /* Includes some pages that were allocated but never written.          */
 GC_API size_t GC_get_heap_size GC_PROTO((void));
 
+/* Return a lower bound on the number of free bytes in the heap.       */
+GC_API size_t GC_get_free_bytes GC_PROTO((void));
+
 /* Return the number of bytes allocated since the last collection.     */
 GC_API size_t GC_get_bytes_since_gc GC_PROTO((void));
 
@@ -341,10 +352,11 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
 
 #ifdef GC_ADD_CALLER
 #  define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
-#  define GC_EXTRA_PARAMS GC_word ra, char * descr_string, int descr_int
+#  define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * descr_string,
+                         int descr_int
 #else
 #  define GC_EXTRAS __FILE__, __LINE__
-#  define GC_EXTRA_PARAMS char * descr_string, int descr_int
+#  define GC_EXTRA_PARAMS GC_CONST char * descr_string, int descr_int
 #endif
 
 /* Debugging (annotated) allocation.  GC_gcollect will check           */
@@ -688,7 +700,7 @@ GC_API void (*GC_is_visible_print_proc)
 # endif /* SOLARIS_THREADS */
 
 
-#if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
 /* We treat these similarly. */
 # include <pthread.h>
 # include <signal.h>
@@ -707,7 +719,7 @@ GC_API void (*GC_is_visible_print_proc)
 
 # if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \
        defined(IRIX_THREADS) || defined(LINUX_THREADS) || \
-       defined(IRIX_JDK_THREADS)
+       defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
        /* Any flavor of threads except SRC_M3. */
 /* This returns a list of objects, linked through their first          */
 /* word.  Its use can greatly reduce lock contention problems, since   */
index 5ce52a7a4a95dcf77ce377765273232c41776073..ac4d63a0b264f4307ccf85f55f2b87bf943ad398 100644 (file)
--- a/gc_priv.h
+++ b/gc_priv.h
@@ -1,6 +1,9 @@
 /* 
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1994 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.
+ *
  *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -64,15 +67,15 @@ typedef char * ptr_t;       /* A generic pointer to which we can add        */
 #       include <stddef.h>
 #   endif
 #   define VOLATILE volatile
-#   define CONST const
 #else
 #   ifdef MSWIN32
 #      include <stdlib.h>
 #   endif
 #   define VOLATILE
-#   define CONST
 #endif
 
+#define CONST GC_CONST
+
 #if 0 /* was once defined for AMIGA */
 #   define GC_FAR __far
 #else
@@ -436,7 +439,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 #  endif
 #  ifdef LINUX_THREADS
 #    include <pthread.h>
-#    ifdef __i386__
+#    if defined(I386)
        inline static int GC_test_and_set(volatile unsigned int *addr) {
          int oldval;
          /* Note: the "xchg" instruction does not need a "lock" prefix */
@@ -446,9 +449,57 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
          return oldval;
        }
 #    else
-       -- > Need implementation of GC_test_and_set()
+#     if defined(POWERPC)
+       inline static int GC_test_and_set(volatile unsigned int *addr) {
+        int oldval;
+        int temp = 1; // locked value
+
+        __asm__ __volatile__(
+               "1:\tlwarx %0,0,%3\n"   // load and reserve
+               "\tcmpwi %0, 0\n"       // if load is
+               "\tbne 2f\n"            //   non-zero, return already set
+               "\tstwcx. %2,0,%1\n"    // else store conditional
+               "\tbne- 1b\n"           // retry if lost reservation
+               "2:\t\n"                // oldval is zero if we set
+              : "=&r"(oldval), "=p"(addr)
+              : "r"(temp), "1"(addr)
+              : "memory");
+        return (int)oldval;
+       }
+#     else
+#      ifdef ALPHA
+         inline static int GC_test_and_set(volatile unsigned int *
+addr)
+         {
+           unsigned long oldvalue;
+           unsigned long temp;
+
+           __asm__ __volatile__(
+                                "1:     ldl_l %0,%1\n"
+                                "       and %0,%3,%2\n"
+                                "       bne %2,2f\n"
+                                "       xor %0,%3,%0\n"
+                                "       stl_c %0,%1\n"
+                                "       beq %0,3f\n"
+                                "       mb\n"
+                                "2:\n"
+                                ".section .text2,\"ax\"\n"
+                                "3:     br 1b\n"
+                                ".previous"
+                                :"=&r" (temp), "=m" (*addr), "=&r"
+(oldvalue)
+                                :"Ir" (1), "m" (*addr));
+
+           return oldvalue;
+         }
+#      else
+         -- > Need implementation of GC_test_and_set()
+#      endif
+#     endif
 #    endif
-#    define GC_clear(addr) (*(addr) = 0)
+     inline static void GC_clear(volatile unsigned int *addr) {
+          *(addr) = 0;
+     }
 
      extern volatile unsigned int GC_allocate_lock;
        /* This is not a mutex because mutexes that obey the (optional)     */
@@ -462,15 +513,10 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 #    define NO_THREAD (pthread_t)(-1)
 #    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD
 #    define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self()))
-#    ifdef UNDEFINED
-#      define LOCK() pthread_mutex_lock(&GC_allocate_ml)
-#      define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
-#    else
-#      define LOCK() \
+#    define LOCK() \
                { if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); }
-#      define UNLOCK() \
+#    define UNLOCK() \
                GC_clear(&GC_allocate_lock)
-#    endif
      extern GC_bool GC_collecting;
 #    define ENTER_GC() \
                { \
@@ -478,15 +524,30 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
                }
 #    define EXIT_GC() GC_collecting = 0;
 #  endif /* LINUX_THREADS */
-#  if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS)
+#  if defined(HPUX_THREADS)
 #    include <pthread.h>
-#    include <mutex.h>
+     extern pthread_mutex_t GC_allocate_ml;
+#    define LOCK() pthread_mutex_lock(&GC_allocate_ml)
+#    define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
+#  endif
+#  if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS) 
+     /* This may also eventually be appropriate for HPUX_THREADS */
+#    include <pthread.h>
+#    ifndef HPUX_THREADS
+       /* This probably should never be included, but I can't test     */
+       /* on Irix anymore.                                             */
+#       include <mutex.h>
+#    endif
 
-#    if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
+#    ifndef HPUX_THREADS
+#      if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
        || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
 #        define GC_test_and_set(addr, v) test_and_set(addr,v)
-#    else
+#      else
 #       define GC_test_and_set(addr, v) __test_and_set(addr,v)
+#      endif
+#    else
+       /* I couldn't find a way to do this inline on HP/UX     */
 #    endif
      extern unsigned long GC_allocate_lock;
        /* This is not a mutex because mutexes that obey the (optional)         */
@@ -500,15 +561,17 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 #    define NO_THREAD (pthread_t)(-1)
 #    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD
 #    define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self()))
-#    ifdef UNDEFINED
-#      define LOCK() pthread_mutex_lock(&GC_allocate_ml)
-#      define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
+#    ifdef HPUX_THREADS
+#      define LOCK() { if (!GC_test_and_clear(&GC_allocate_lock)) GC_lock(); }
+       /* The following is INCORRECT, since the memory model is too weak. */
+#      define UNLOCK() { GC_noop1(&GC_allocate_lock); \
+                       *(volatile unsigned long *)(&GC_allocate_lock) = 1; }
 #    else
-#      define LOCK() { if (GC_test_and_set(&GC_allocate_lock, 1)) GC_lock(); }
-#       if __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) \
+#      define LOCK() { if (GC_test_and_set(&GC_allocate_lock, 1)) GC_lock(); }
+#      if __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) \
           && defined(_COMPILER_VERSION) && _COMPILER_VERSION >= 700
 #          define UNLOCK() __lock_release(&GC_allocate_lock)
-#      else
+#      else
            /* The function call in the following should prevent the    */
            /* compiler from moving assignments to below the UNLOCK.    */
            /* This is probably not necessary for ucode or gcc 2.8.     */
@@ -516,7 +579,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
            /* versions.                                                */
 #           define UNLOCK() { GC_noop1(&GC_allocate_lock); \
                        *(volatile unsigned long *)(&GC_allocate_lock) = 0; }
-#      endif
+#      endif
 #    endif
      extern GC_bool GC_collecting;
 #    define ENTER_GC() \
@@ -607,7 +670,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 # else
 #   if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
        || defined(IRIX_THREADS) || defined(LINUX_THREADS) \
-       || defined(IRIX_JDK_THREADS)
+       || defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
       void GC_stop_world();
       void GC_start_world();
 #     define STOP_WORLD() GC_stop_world()
@@ -857,6 +920,9 @@ struct hblkhdr {
                            /* object starting at the ith word (header      */
                            /* INCLUDED) in the heap block.                 */
                            /* The lsb of word 0 is numbered 0.             */
+                           /* Unused bits are invalid, and are             */
+                           /* occasionally set, e.g for uncollectable      */
+                           /* objects.                                     */
 };
 
 /*  heap block body */
@@ -1411,8 +1477,14 @@ extern void (*GC_start_call_back)(/* void */);
                        /* lock held.                                   */
                        /* 0 by default.                                */
 void GC_push_regs();   /* Push register contents onto mark stack.      */
+                       /* If NURSERY is defined, the default push      */
+                       /* action can be overridden with GC_push_proc   */
 void GC_remark();      /* Mark from all marked objects.  Used  */
                        /* only if we had to drop something.    */
+
+# ifdef NURSERY
+    extern void (*GC_push_proc)(ptr_t);
+# endif
 # if defined(MSWIN32)
   void __cdecl GC_push_one();
 # else
index c9017d371a8a7f73ac9e08faf498d9f9ffa2aa93..a70010898d121dafd4f2a5bec183cf5cf259979c 100644 (file)
 #    define NETBSD
 #    define mach_type_known
 # endif
+# if defined(__NetBSD__) && defined(arm32)
+#    define ARM32
+#    define NETBSD
+#    define mach_type_known
+# endif
 # if defined(vax)
 #    define VAX
 #    ifdef ultrix
 #   define SYSV
 #   define mach_type_known
 # endif
-# if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) \
+# if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
      || defined(hppa) || defined(__hppa__)
 #   define HP_PA
+#   ifndef LINUX
+#     define HPUX
+#   endif
 #   define mach_type_known
 # endif
 # if defined(LINUX) && (defined(i386) || defined(__i386__))
 #    define I386
 #    define mach_type_known
 # endif
+# if defined(LINUX) && (defined(__ia64__) || defined(__ia64))
+#    define IA64
+#    define mach_type_known
+# endif
 # if defined(LINUX) && defined(powerpc)
 #    define POWERPC
 #    define mach_type_known
 #   define UTS4
 #   define mach_type_known
 # endif
+# if defined(__pj__)
+#   define PJ
+#   define mach_type_known
+# endif
 /* Ivan Demakov */
 # if defined(__WATCOMC__) && defined(__386__)
 #   define I386
 #     define STACK_GRAN 0x10000000
        /* Stack usually starts at 0x80000000 */
 #     define DATASTART GC_data_start
+       /* Others have reported better success with */
+        /*     extern int __data_start;            */
+       /*#     define DATASTART (&__data_start)    */
+       /* and disabling the GC_data_start          */
+       /* initialization code.                     */
       extern int _end;
 #     define DATAEND (&_end)
 #   endif
 # endif
 
 # ifdef HP_PA
+    /* OS is assumed to be HP/UX       */
 #   define MACH_TYPE "HP_PA"
-#   define ALIGNMENT 4
-#   define ALIGN_DOUBLE
+#   define OS_TYPE "HPUX"
+#   ifdef __LP64__
+#     define CPP_WORDSZ 64
+#     define ALIGNMENT 8
+#   else
+#     define CPP_WORDSZ 32
+#     define ALIGNMENT 4
+#     define ALIGN_DOUBLE
+#   endif
     extern int __data_start;
 #   define DATASTART ((ptr_t)(&__data_start))
 #   if 0
 #   endif
 #   define STACK_GROWS_UP
 #   define DYNAMIC_LOADING
+#   ifndef HPUX_THREADS
+#     define MPROTECT_VDB
+#   endif
 #   include <unistd.h>
 #   define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
        /* They misspelled the Posix macro?     */
 #   endif
 # endif
 
+# ifdef IA64
+#   define MACH_TYPE "IA64"
+#   define ALIGN_DOUBLE
+       /* Requires 16 byte alignment for malloc */
+#   define ALIGNMENT 8
+#   ifdef HPUX
+       --> needs work
+#   endif
+#   ifdef LINUX
+#       define OS_TYPE "LINUX"
+#       define CPP_WORDSZ 64
+       /* This should really be done through /proc, but that   */
+       /* requires we run on an IA64 kernel.                   */
+#       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)
+       /* We also need the base address of the register stack  */
+       /* backing store.  There is probably a better way to    */
+       /* get that, too ...                                    */
+#      define BACKING_STORE_BASE ((ptr_t) 0x9fffffff80000000l)
+#       define DATASTART GC_data_start
+#       define DYNAMIC_LOADING
+       extern int _end;
+#      define DATAEND (&_end)
+#   endif
+# endif
+
 # ifdef M88K
 #   define MACH_TYPE "M88K"
 #   define ALIGNMENT 4
 #      define HEURISTIC2
 # endif
 
+# if defined(PJ)
+#   define ALIGNMENT 4
+    extern int _etext;
+#   define DATASTART ((ptr_t)(&_etext))
+#   define HEURISTIC1
+# endif
+
+# ifdef ARM32
+#   define CPP_WORDSZ 32
+#   define MACH_TYPE "ARM32"
+#   define ALIGNMENT 4
+#   ifdef NETBSD
+#       define OS_TYPE "NETBSD"
+#       define HEURISTIC2
+        extern char etext;
+#       define DATASTART ((ptr_t)(&etext))
+#       define USE_GENERIC_PUSH_REGS
+#   endif
+#endif
+
 # ifndef STACK_GROWS_UP
 #   define STACK_GROWS_DOWN
 # endif
 #   define SUNOS5SIGS
 # endif
 
+# if defined(HPUX)
+#   define SUNOS5SIGS
+# endif
+
 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
    -> bad word size
 # endif
 # if defined(SOLARIS_THREADS) && !defined(SUNOS5)
 --> inconsistent configuration
 # endif
+# if defined(HPUX_THREADS) && !defined(HPUX)
+--> inconsistent configuration
+# endif
 # if defined(PCR) || defined(SRC_M3) || \
        defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \
        defined(IRIX_THREADS) || defined(LINUX_THREADS) || \
-       defined(IRIX_JDK_THREADS)
+       defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
 #   define THREADS
 # endif
 
similarity index 85%
rename from irix_threads.c
rename to hpux_irix_threads.c
index 5efca2110343942b2adf44a736b25cb0af4067ae..a5b2cce5f85e24a19ec3c96f64364f4e6ba2ad78 100644 (file)
@@ -1,6 +1,7 @@
 /* 
- * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
+ * 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.
  *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  * 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 linux_threads.c
- * and irix_threads.c; any changes made here may need to be reflected
+ * and hpux_irix_threads.c; any changes made here may need to be reflected
  * there too.
  */
 
-# if defined(IRIX_THREADS)
+# if defined(IRIX_THREADS) || defined(HPUX_THREADS)
+
+# if defined(HPUX_THREADS)
+#   include <sys/semaphore.h>
+# endif
 
 # include "gc_priv.h"
 # include <pthread.h>
@@ -169,8 +177,12 @@ ptr_t GC_stack_alloc(size_t * stack_size)
         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. */
-        /* mprotect(result, GC_page_sz, PROT_NONE); */
-        result += GC_page_sz;
+#      ifdef STACK_GROWS_UP
+          /* mprotect(result + search_sz, GC_page_sz, PROT_NONE); */
+#      else
+          /* mprotect(result, GC_page_sz, PROT_NONE); */
+          result += GC_page_sz;
+#      endif
     }
     *stack_size = search_sz;
     return(result);
@@ -381,7 +393,7 @@ void GC_push_all_stacks()
     register int i;
     register GC_thread p;
     register ptr_t sp = GC_approx_sp();
-    register ptr_t lo, hi;
+    register ptr_t hot, cold;
     pthread_t me = pthread_self();
     
     if (!GC_thr_initialized) GC_thr_init();
@@ -390,17 +402,25 @@ void GC_push_all_stacks()
       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();
+           hot = GC_approx_sp();
        } else {
-           lo = p -> stack_ptr;
+           hot = p -> stack_ptr;
        }
         if (p -> stack_size != 0) {
-            hi = p -> stack + p -> stack_size;
+#        ifdef STACK_GROWS_UP
+           cold = p -> stack;
+#        else
+            cold = p -> stack + p -> stack_size;
+#        endif
         } else {
             /* The original stack. */
-            hi = GC_stackbottom;
+            cold = GC_stackbottom;
         }
-        GC_push_all_stack(lo, hi);
+#      ifdef STACK_GROWS_UP
+          GC_push_all_stack(cold, hot);
+#      else
+          GC_push_all_stack(hot, cold);
+#      endif
       }
     }
 }
@@ -531,6 +551,40 @@ void * GC_start_routine(void * arg)
     return(result);
 }
 
+# ifdef HPUX_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;
+    pthread_spu_t ps_tmp;
+    (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);
+    (void) pthread_attr_getprocessor_np(source, &ps_tmp, &tmp);
+    (void) pthread_attr_setprocessor_np(pa_ptr, ps_tmp, tmp);
+  }
+# else
+#   define copy_attr(pa_ptr, source) *(pa_ptr) = *(source)
+# endif
+
 int
 GC_pthread_create(pthread_t *new_thread,
                  const pthread_attr_t *attr,
@@ -548,7 +602,9 @@ GC_pthread_create(pthread_t *new_thread,
        /* library, which isn't visible to the collector.                */
 
     if (0 == si) return(ENOMEM);
-    sem_init(&(si -> registered), 0, 0);
+    if (0 != sem_init(&(si -> registered), 0, 0)) {
+        ABORT("sem_init failed");
+    }
     si -> start_routine = start_routine;
     si -> arg = arg;
     LOCK();
@@ -557,7 +613,7 @@ GC_pthread_create(pthread_t *new_thread,
         stack = 0;
        (void) pthread_attr_init(&new_attr);
     } else {
-        new_attr = *attr;
+       copy_attr(&new_attr, attr);
        pthread_attr_getstackaddr(&new_attr, &stack);
     }
     pthread_attr_getstacksize(&new_attr, &stacksize);
@@ -586,24 +642,39 @@ GC_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.                                       */
-        if (0 != sem_wait(&(si -> registered))) ABORT("sem_wait failed");
+        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); */
+    pthread_attr_destroy(&new_attr);  /* Not a no-op under HPUX */
     return(result);
 }
 
+#ifndef HPUX_THREADS
+/* For now we use the pthreads locking primitives on HP/UX */
+
 GC_bool GC_collecting = 0; /* A hint that we're in the collector and       */
                         /* holding the allocation lock for an           */
                         /* extended period.                             */
 
 /* Reasonably fast spin locks.  Basically the same implementation */
-/* as STL alloc.h.  This isn't really the right way to do this.   */
-/* but until the POSIX scheduling mess gets straightened out ...  */
-
-unsigned long GC_allocate_lock = 0;
+/* as STL alloc.h.                                               */
 
 #define SLEEP_THRESHOLD 3
 
+#ifdef HPUX
+   unsigned long GC_allocate_lock = 1;
+#  define GC_TRY_LOCK() GC_test_and_clear(&GC_allocate_lock)
+#  define GC_LOCK_TAKEN !GC_allocate_lock
+#else
+   unsigned long GC_allocate_lock = 0;
+#  define GC_TRY_LOCK() !GC_test_and_set(&GC_allocate_lock,1)
+#  define GC_LOCK_TAKEN GC_allocate_lock
+#endif
+
 void GC_lock()
 {
 #   define low_spin_max 30  /* spin cycles if we suspect uniprocessor */
@@ -616,7 +687,7 @@ void GC_lock()
 #   define PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk
     int i;
 
-    if (!GC_test_and_set(&GC_allocate_lock, 1)) {
+    if (GC_TRY_LOCK()) {
         return;
     }
     junk = 0;
@@ -624,11 +695,11 @@ void GC_lock()
     my_last_spins = last_spins;
     for (i = 0; i < my_spin_max; i++) {
         if (GC_collecting) goto yield;
-        if (i < my_last_spins/2 || GC_allocate_lock) {
+        if (i < my_last_spins/2 || GC_LOCK_TAKEN) {
             PAUSE; 
             continue;
         }
-        if (!GC_test_and_set(&GC_allocate_lock, 1)) {
+        if (GC_TRY_LOCK()) {
            /*
              * got it!
              * Spinning worked.  Thus we're probably not being scheduled
@@ -644,7 +715,7 @@ void GC_lock()
     spin_max = low_spin_max;
 yield:
     for (i = 0;; ++i) {
-        if (!GC_test_and_set(&GC_allocate_lock, 1)) {
+        if (GC_TRY_LOCK()) {
             return;
         }
         if (i < SLEEP_THRESHOLD) {
@@ -662,7 +733,7 @@ yield:
     }
 }
 
-
+#endif /* !HPUX_THREADS */
 
 # else
 
diff --git a/hpux_test_and_clear.s b/hpux_test_and_clear.s
new file mode 100644 (file)
index 0000000..f09b211
--- /dev/null
@@ -0,0 +1,21 @@
+       .SPACE $PRIVATE$
+       .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+       .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+       .SPACE $TEXT$
+       .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+       .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+       .IMPORT $global$,DATA
+       .IMPORT $$dyncall,MILLICODE
+       .SPACE $TEXT$
+       .SUBSPA $CODE$
+
+       .align 4
+       .EXPORT GC_test_and_clear,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+GC_test_and_clear
+       .PROC
+       .CALLINFO FRAME=0,NO_CALLS
+       .ENTRY
+       ldcw,co (%r26),%r28
+       bv,n 0(%r2)
+       .EXIT
+       .PROCEND
index 306140953140520f39ab5e3064e588b968e9aa78..cc74765d098ef28993593971faef5d5105cefe2f 100644 (file)
 # if defined(__STDC__) || defined(__cplusplus)
 #   define GC_PROTO(args) args
     typedef void * GC_PTR;
+#   define GC_CONST const
 # else
 #   define GC_PROTO(args) ()
     typedef char * GC_PTR;
+#   define GC_CONST
 #  endif
 
 # ifdef __cplusplus
@@ -131,6 +133,12 @@ GC_API int GC_dont_expand;
 GC_API int GC_full_freq;    /* Number of partial collections between   */
                            /* full collections.  Matters only if       */
                            /* GC_incremental is set.                   */
+                           /* Full collections are also triggered if   */
+                           /* the collector detects a substantial      */
+                           /* increase in the number of in-use heap    */
+                           /* blocks.  Values in the tens are now      */
+                           /* perfectly reasonable, unlike for         */
+                           /* earlier GC versions.                     */
                        
 GC_API GC_word GC_non_gc_bytes;
                        /* Bytes not considered candidates for collection. */
@@ -297,6 +305,9 @@ GC_API int GC_try_to_collect GC_PROTO((GC_stop_func stop_func));
 /* Includes some pages that were allocated but never written.          */
 GC_API size_t GC_get_heap_size GC_PROTO((void));
 
+/* Return a lower bound on the number of free bytes in the heap.       */
+GC_API size_t GC_get_free_bytes GC_PROTO((void));
+
 /* Return the number of bytes allocated since the last collection.     */
 GC_API size_t GC_get_bytes_since_gc GC_PROTO((void));
 
@@ -341,10 +352,11 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
 
 #ifdef GC_ADD_CALLER
 #  define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
-#  define GC_EXTRA_PARAMS GC_word ra, char * descr_string, int descr_int
+#  define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * descr_string,
+                         int descr_int
 #else
 #  define GC_EXTRAS __FILE__, __LINE__
-#  define GC_EXTRA_PARAMS char * descr_string, int descr_int
+#  define GC_EXTRA_PARAMS GC_CONST char * descr_string, int descr_int
 #endif
 
 /* Debugging (annotated) allocation.  GC_gcollect will check           */
@@ -688,7 +700,7 @@ GC_API void (*GC_is_visible_print_proc)
 # endif /* SOLARIS_THREADS */
 
 
-#if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
 /* We treat these similarly. */
 # include <pthread.h>
 # include <signal.h>
@@ -707,7 +719,7 @@ GC_API void (*GC_is_visible_print_proc)
 
 # if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \
        defined(IRIX_THREADS) || defined(LINUX_THREADS) || \
-       defined(IRIX_JDK_THREADS)
+       defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
        /* Any flavor of threads except SRC_M3. */
 /* This returns a list of objects, linked through their first          */
 /* word.  Its use can greatly reduce lock contention problems, since   */
similarity index 100%
rename from gc_copy_descr.h
rename to include/gc_copy_descr.h
similarity index 100%
rename from nursery.h
rename to include/gc_nursery.h
index 577138830c58c875d6eec423145abb1b8fca6b60..54b7bd448d86d165873a9a8f9a028bdfbe368722 100644 (file)
@@ -318,12 +318,10 @@ class traceable_alloc_template {
 
 typedef traceable_alloc_template < 0 > traceable_alloc;
 
-#ifdef _SGI_SOURCE
-
 // We want to specialize simple_alloc so that it does the right thing
 // for all pointerfree types.  At the moment there is no portable way to
 // even approximate that.  The following approximation should work for
-// SGI compilers, and perhaps some others.
+// SGI compilers, and recent versions of g++.
 
 # define __GC_SPECIALIZE(T,alloc) \
 class simple_alloc<T, alloc> { \
@@ -451,6 +449,4 @@ __STL_END_NAMESPACE
 
 #endif /* __STL_USE_STD_ALLOCATORS */
 
-#endif /* _SGI_SOURCE */
-
 #endif /* GC_ALLOC_H */
index 5ce52a7a4a95dcf77ce377765273232c41776073..ac4d63a0b264f4307ccf85f55f2b87bf943ad398 100644 (file)
@@ -1,6 +1,9 @@
 /* 
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1994 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.
+ *
  *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -64,15 +67,15 @@ typedef char * ptr_t;       /* A generic pointer to which we can add        */
 #       include <stddef.h>
 #   endif
 #   define VOLATILE volatile
-#   define CONST const
 #else
 #   ifdef MSWIN32
 #      include <stdlib.h>
 #   endif
 #   define VOLATILE
-#   define CONST
 #endif
 
+#define CONST GC_CONST
+
 #if 0 /* was once defined for AMIGA */
 #   define GC_FAR __far
 #else
@@ -436,7 +439,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 #  endif
 #  ifdef LINUX_THREADS
 #    include <pthread.h>
-#    ifdef __i386__
+#    if defined(I386)
        inline static int GC_test_and_set(volatile unsigned int *addr) {
          int oldval;
          /* Note: the "xchg" instruction does not need a "lock" prefix */
@@ -446,9 +449,57 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
          return oldval;
        }
 #    else
-       -- > Need implementation of GC_test_and_set()
+#     if defined(POWERPC)
+       inline static int GC_test_and_set(volatile unsigned int *addr) {
+        int oldval;
+        int temp = 1; // locked value
+
+        __asm__ __volatile__(
+               "1:\tlwarx %0,0,%3\n"   // load and reserve
+               "\tcmpwi %0, 0\n"       // if load is
+               "\tbne 2f\n"            //   non-zero, return already set
+               "\tstwcx. %2,0,%1\n"    // else store conditional
+               "\tbne- 1b\n"           // retry if lost reservation
+               "2:\t\n"                // oldval is zero if we set
+              : "=&r"(oldval), "=p"(addr)
+              : "r"(temp), "1"(addr)
+              : "memory");
+        return (int)oldval;
+       }
+#     else
+#      ifdef ALPHA
+         inline static int GC_test_and_set(volatile unsigned int *
+addr)
+         {
+           unsigned long oldvalue;
+           unsigned long temp;
+
+           __asm__ __volatile__(
+                                "1:     ldl_l %0,%1\n"
+                                "       and %0,%3,%2\n"
+                                "       bne %2,2f\n"
+                                "       xor %0,%3,%0\n"
+                                "       stl_c %0,%1\n"
+                                "       beq %0,3f\n"
+                                "       mb\n"
+                                "2:\n"
+                                ".section .text2,\"ax\"\n"
+                                "3:     br 1b\n"
+                                ".previous"
+                                :"=&r" (temp), "=m" (*addr), "=&r"
+(oldvalue)
+                                :"Ir" (1), "m" (*addr));
+
+           return oldvalue;
+         }
+#      else
+         -- > Need implementation of GC_test_and_set()
+#      endif
+#     endif
 #    endif
-#    define GC_clear(addr) (*(addr) = 0)
+     inline static void GC_clear(volatile unsigned int *addr) {
+          *(addr) = 0;
+     }
 
      extern volatile unsigned int GC_allocate_lock;
        /* This is not a mutex because mutexes that obey the (optional)     */
@@ -462,15 +513,10 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 #    define NO_THREAD (pthread_t)(-1)
 #    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD
 #    define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self()))
-#    ifdef UNDEFINED
-#      define LOCK() pthread_mutex_lock(&GC_allocate_ml)
-#      define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
-#    else
-#      define LOCK() \
+#    define LOCK() \
                { if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); }
-#      define UNLOCK() \
+#    define UNLOCK() \
                GC_clear(&GC_allocate_lock)
-#    endif
      extern GC_bool GC_collecting;
 #    define ENTER_GC() \
                { \
@@ -478,15 +524,30 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
                }
 #    define EXIT_GC() GC_collecting = 0;
 #  endif /* LINUX_THREADS */
-#  if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS)
+#  if defined(HPUX_THREADS)
 #    include <pthread.h>
-#    include <mutex.h>
+     extern pthread_mutex_t GC_allocate_ml;
+#    define LOCK() pthread_mutex_lock(&GC_allocate_ml)
+#    define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
+#  endif
+#  if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS) 
+     /* This may also eventually be appropriate for HPUX_THREADS */
+#    include <pthread.h>
+#    ifndef HPUX_THREADS
+       /* This probably should never be included, but I can't test     */
+       /* on Irix anymore.                                             */
+#       include <mutex.h>
+#    endif
 
-#    if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
+#    ifndef HPUX_THREADS
+#      if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
        || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
 #        define GC_test_and_set(addr, v) test_and_set(addr,v)
-#    else
+#      else
 #       define GC_test_and_set(addr, v) __test_and_set(addr,v)
+#      endif
+#    else
+       /* I couldn't find a way to do this inline on HP/UX     */
 #    endif
      extern unsigned long GC_allocate_lock;
        /* This is not a mutex because mutexes that obey the (optional)         */
@@ -500,15 +561,17 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 #    define NO_THREAD (pthread_t)(-1)
 #    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD
 #    define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self()))
-#    ifdef UNDEFINED
-#      define LOCK() pthread_mutex_lock(&GC_allocate_ml)
-#      define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
+#    ifdef HPUX_THREADS
+#      define LOCK() { if (!GC_test_and_clear(&GC_allocate_lock)) GC_lock(); }
+       /* The following is INCORRECT, since the memory model is too weak. */
+#      define UNLOCK() { GC_noop1(&GC_allocate_lock); \
+                       *(volatile unsigned long *)(&GC_allocate_lock) = 1; }
 #    else
-#      define LOCK() { if (GC_test_and_set(&GC_allocate_lock, 1)) GC_lock(); }
-#       if __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) \
+#      define LOCK() { if (GC_test_and_set(&GC_allocate_lock, 1)) GC_lock(); }
+#      if __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) \
           && defined(_COMPILER_VERSION) && _COMPILER_VERSION >= 700
 #          define UNLOCK() __lock_release(&GC_allocate_lock)
-#      else
+#      else
            /* The function call in the following should prevent the    */
            /* compiler from moving assignments to below the UNLOCK.    */
            /* This is probably not necessary for ucode or gcc 2.8.     */
@@ -516,7 +579,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
            /* versions.                                                */
 #           define UNLOCK() { GC_noop1(&GC_allocate_lock); \
                        *(volatile unsigned long *)(&GC_allocate_lock) = 0; }
-#      endif
+#      endif
 #    endif
      extern GC_bool GC_collecting;
 #    define ENTER_GC() \
@@ -607,7 +670,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 # else
 #   if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
        || defined(IRIX_THREADS) || defined(LINUX_THREADS) \
-       || defined(IRIX_JDK_THREADS)
+       || defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
       void GC_stop_world();
       void GC_start_world();
 #     define STOP_WORLD() GC_stop_world()
@@ -857,6 +920,9 @@ struct hblkhdr {
                            /* object starting at the ith word (header      */
                            /* INCLUDED) in the heap block.                 */
                            /* The lsb of word 0 is numbered 0.             */
+                           /* Unused bits are invalid, and are             */
+                           /* occasionally set, e.g for uncollectable      */
+                           /* objects.                                     */
 };
 
 /*  heap block body */
@@ -1411,8 +1477,14 @@ extern void (*GC_start_call_back)(/* void */);
                        /* lock held.                                   */
                        /* 0 by default.                                */
 void GC_push_regs();   /* Push register contents onto mark stack.      */
+                       /* If NURSERY is defined, the default push      */
+                       /* action can be overridden with GC_push_proc   */
 void GC_remark();      /* Mark from all marked objects.  Used  */
                        /* only if we had to drop something.    */
+
+# ifdef NURSERY
+    extern void (*GC_push_proc)(ptr_t);
+# endif
 # if defined(MSWIN32)
   void __cdecl GC_push_one();
 # else
index 536986049985bab7bb04925c8529de6a8865afa7..52f863467619385913d786b8daff604d4fe3700a 100644 (file)
@@ -62,6 +62,12 @@ asm static void PushMacRegisters()
 
 #endif /* __MWERKS__ */
 
+# if defined(SPARC) || defined(IA64)
+    /* Value returned from register flushing routine; either sp (SPARC) */
+    /* or ar.bsp (IA64)                                                        */
+    word GC_save_regs_ret_val;
+# endif
+
 /* Routine to mark from registers that are preserved by the C compiler. */
 /* This must be ported to every new architecture.  There is a generic   */
 /* version at the end, that is likely, but not guaranteed to work       */
@@ -268,12 +274,12 @@ void GC_push_regs()
          asm ("movd r7, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
 #       endif
 
-#       ifdef SPARC
+#       if defined(SPARC) || defined(IA64)
          {
              word GC_save_regs_in_stack();
              
              /* generic code will not work */
-             (void)GC_save_regs_in_stack();
+             GC_save_regs_ret_val = GC_save_regs_in_stack();
          }
 #       endif
 
@@ -333,12 +339,22 @@ void GC_push_regs()
 #        endif /* !__GNUC__ */
 #       endif /* M68K/SYSV */
 
+#     if defined(PJ)
+       {
+           register int * sp asm ("optop");
+           extern int *__libc_stack_end;
+
+           GC_push_all_stack (sp, __libc_stack_end);
+        }
+#     endif
 
       /* other machines... */
 #       if !(defined M68K) && !(defined VAX) && !(defined RT) 
 #      if !(defined SPARC) && !(defined I386) && !(defined NS32K)
-#      if !defined(POWERPC) && !defined(UTS4)
+#      if !defined(POWERPC) && !defined(UTS4) && !defined(IA64)
+#       if !defined(PJ)
            --> bad news <--
+#      endif
 #       endif
 #       endif
 #       endif
@@ -398,6 +414,27 @@ ptr_t cold_gc_frame;
 #   endif
 # endif
 
+/* On IA64, we also need to flush register windows.  But they end      */
+/* up on the other side of the stack segment.                          */
+/* Returns the backing store pointer for the register stack.           */
+# ifdef IA64
+       asm("        .text");
+       asm("        .psr abi64");
+       asm("        .psr lsb");
+       asm("        .lsb");
+       asm("");
+       asm("        .text");
+       asm("        .align 16");
+       asm("        .global GC_save_regs_in_stack");
+       asm("        .proc GC_save_regs_in_stack");
+       asm("GC_save_regs_in_stack:");
+       asm("        .body");
+       asm("        flushrs");
+       asm("        ;;");
+       asm("        mov r8=ar.bsp");
+       asm("        br.ret.sptk.few rp");
+       asm("        .endp GC_save_regs_in_stack");
+# endif
 
 /* GC_clear_stack_inner(arg, limit) clears stack area up to limit and  */
 /* returns arg.  Stack clearing is crucial on SPARC, so we supply      */
diff --git a/mark.c b/mark.c
index 34db472a66f09d83d7f1a78a1e6d814ca201c767..67085fbcc294dc0b58fdca5cdfa4bf723f765e31 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -87,6 +87,10 @@ struct obj_kind GC_obj_kinds[MAXOBJKINDS] = {
 #   define INITIAL_MARK_STACK_SIZE (1*HBLKSIZE)
                /* INITIAL_MARK_STACK_SIZE * sizeof(mse) should be a    */
                /* multiple of HBLKSIZE.                                */
+               /* The incremental collector actually likes a larger    */
+               /* size, since it want to push all marked dirty objs    */
+               /* before marking anything new.  Currently we let it    */
+               /* grow dynamically.                                    */
 # endif
 
 /*
@@ -254,7 +258,12 @@ ptr_t cold_gc_frame;
            
        case MS_PUSH_RESCUERS:
            if (GC_mark_stack_top
-               >= GC_mark_stack + INITIAL_MARK_STACK_SIZE/4) {
+               >= GC_mark_stack + GC_mark_stack_size
+                  - INITIAL_MARK_STACK_SIZE/2) {
+               /* Go ahead and mark, even though that might cause us to */
+               /* see more marked dirty objects later on.  Avoid this   */
+               /* in the future.                                        */
+               GC_mark_stack_too_small = TRUE;
                GC_mark_from_mark_stack();
                return(FALSE);
            } else {
@@ -671,6 +680,12 @@ int all;
 # endif
 word p;
 {
+#   ifdef NURSERY
+      if (0 != GC_push_proc) {
+       GC_push_proc(p);
+       return;
+      }
+#   endif
     GC_PUSH_ONE_STACK(p, 0);
 }
 
@@ -1115,7 +1130,7 @@ struct hblk *h;
 struct hblk * GC_push_next_marked_dirty(h)
 struct hblk *h;
 {
-    register hdr * hhdr = HDR(h);
+    register hdr * hhdr;
     
     if (!GC_dirty_maintained) { ABORT("dirty bits not set up"); }
     for (;;) {
index 2f21ed324dd7c2d06724d52b12d2063c955b4a41..0e84f2732fc414039d73154fac36269550c98ba3 100644 (file)
@@ -412,6 +412,9 @@ ptr_t cold_gc_frame;
        if (0 == cold_gc_frame) return;
 #       ifdef STACK_GROWS_DOWN
          GC_push_all_eager(GC_approx_sp(), cold_gc_frame);
+#        ifdef IA64
+           --> fix this
+#        endif
 #       else
          GC_push_all_eager( cold_gc_frame, GC_approx_sp() );
 #       endif
@@ -419,6 +422,31 @@ ptr_t cold_gc_frame;
 #      ifdef STACK_GROWS_DOWN
            GC_push_all_stack_partially_eager( GC_approx_sp(), GC_stackbottom,
                                               cold_gc_frame );
+#          ifdef IA64
+             /* We also need to push the register stack backing store. */
+             /* This should really be done in the same way as the      */
+             /* regular stack.  For now we fudge it a bit.             */
+             /* Note that the backing store grows up, so we can't use  */
+             /* GC_push_all_stack_partially_eager.                     */
+             {
+               extern word GC_save_regs_ret_val;
+                       /* Previously set to backing store pointer.     */
+               ptr_t bsp = (ptr_t) GC_save_regs_ret_val;
+               ptr_t cold_gc_bs_pointer;
+#              ifdef ALL_INTERIOR_POINTERS
+                 cold_gc_bs_pointer = bsp - 2048;
+                 if (cold_gc_bs_pointer < BACKING_STORE_BASE) {
+                   cold_gc_bs_pointer = BACKING_STORE_BASE;
+                 }
+                 GC_push_all(BACKING_STORE_BASE, cold_gc_bs_pointer);
+#              else
+                 cold_gc_bs_pointer = BACKING_STORE_BASE;
+#              endif
+               GC_push_all_eager(cold_gc_bs_pointer, bsp);
+               /* All values should be sufficiently aligned that we    */
+               /* dont have to worry about the boundary.               */
+             }
+#          endif
 #       else
            GC_push_all_stack_partially_eager( GC_stackbottom, GC_approx_sp(),
                                               cold_gc_frame );
diff --git a/misc.c b/misc.c
index c3fce63dc2ea334d7ba15b6ba735b4386d19f761..40cbe97de9f4f65340269931c181520c0f87d393 100644 (file)
--- a/misc.c
+++ b/misc.c
 #          else
 #             if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
                 || defined(IRIX_JDK_THREADS)
-#              ifdef UNDEFINED
-                   pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER;
-#              endif
                pthread_t GC_lock_holder = NO_THREAD;
 #            else
-               --> declare allocator lock here
+#              if defined(HPUX_THREADS)
+                 pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER;
+#              else 
+                 --> declare allocator lock here
+#              endif
 #            endif
 #         endif
 #      endif
@@ -391,6 +392,11 @@ size_t GC_get_heap_size GC_PROTO(())
     return ((size_t) GC_heapsize);
 }
 
+size_t GC_get_free_bytes GC_PROTO(())
+{
+    return ((size_t) GC_large_free_bytes);
+}
+
 size_t GC_get_bytes_since_gc GC_PROTO(())
 {
     return ((size_t) WORDS_TO_BYTES(GC_words_allocd));
@@ -433,7 +439,8 @@ void GC_init_inner()
 #   ifdef MSWIN32
        GC_init_win32();
 #   endif
-#   if defined(LINUX) && (defined(POWERPC) || defined(ALPHA) || defined(SPARC))
+#   if defined(LINUX) && \
+       (defined(POWERPC) || defined(ALPHA) || defined(SPARC) || defined(IA64))
        GC_init_linux_data_start();
 #   endif
 #   ifdef SOLARIS_THREADS
@@ -442,11 +449,12 @@ void GC_init_inner()
         GC_dirty_init();
 #   endif
 #   if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
-       || defined(IRIX_JDK_THREADS)
+       || defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
         GC_thr_init();
 #   endif
 #   if !defined(THREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
-       || defined(IRIX_THREADS) || defined(LINUX_THREADS)
+       || defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+       || defined(HPUX_THREADS)
       if (GC_stackbottom == 0) {
        GC_stackbottom = GC_get_stack_base();
       }
index 8bbb1015855364a0e3f07e5a153ca9750afd82c5..ab83afbaaf2f58e38d4a15de2ecba66f3c011683 100644 (file)
--- a/nursery.c
+++ b/nursery.c
  * modified is included with the above copyright notice.
  */
 
-
+#ifdef NURSERY
 ??? This implementation is incomplete.  If you are trying to
 ??? compile this you are doing something wrong.
 
 #include "nursery.h"
 
+#define SCAN_STATICS_FOR_NURSERY
+       /* If this is not defined, the collector will not see   */
+       /* references from static data areas to the nursery.    */
+
 struct copy_obj {
     ptr_t forward;     /* Forwarding link for copied objects.  */
     GC_copy_descriptor descr; /* Object descriptor     */
@@ -68,6 +72,23 @@ unsigned short *GC_pinned;   /* Number of pinned objects in ith      */
 
 GC_copy_alloc_state global_alloc_state = (ptr_t)(-1);  /* will overflow. */
 
+/* Array of known rescuing pointers from the heap to the nursery.      */
+  ptr_t ** nursery_rescuers;
+  /* Pointer to one past the last slot in rescuer table        */
+  ptr_t ** nursery_rescuers_end;
+  /* Maximum number of known rescuing pointers.                        */
+# define MAX_NURSERY_RESCUERS 32*1024
+  /* Add a rescuer to the list */
+# define ADD_NURSERY_RESCUER(p) \
+    if (nursery_rescuers_end >= nursery_rescuers + MAX_NURSERY_RESCUERS) { \
+      ABORT("Nursery recuers overflow"); /* Fix later !!! */ \
+    } else { \
+      *nursery_rescuers_end++ = p; \
+    }
+  /* Remove rescuer at the given position in the table */
+# define REMOVE_RESCUER(p) \
+    *p = *--nursery_rescuers_end
+
 /* Should be called with allocator lock held.  */
 GC_nursery_init() {
     GC_nursery_start = GET_MEM(GC_nursery_size);
@@ -92,44 +113,158 @@ GC_nursery_init() {
     GC_nursery_blocks = GC_nursery_size/NURSERY_BLOCK_SIZE;
     GC_pinned = GC_scratch_alloc(GC_nursery_blocks * sizeof(unsigned short));
     BZERO(GC_pinned, GC_nursery_blocks);
+    nursery_rescuers = GET_MEM(MAX_NURSERY_RESCUERS * sizeof(ptr_t *));
+    nursery_rescuers_end = nursery_rescuers;
+    if (0 == GC_nursery_start || 0 == GC_nursery_map || 0 == nursery_rescuers)
+       ABORT("Insufficient memory for nursery");
+}
+
+#define PIN_OBJ(p) \
+    if (p >= GC_nursery_start && p < GC_nursery_end) { GC_pin_obj_checked(p); }
+
+/* Pin the object at p, if it's in the nursery.        */
+void GC_pin_obj(ptr_t p) {
+    PIN_OBJ(p);
+}
+
+void (*GC_push_proc)(ptr_t) = 0;
+
+/* Pin the object at p, which is known to be in the nursery.   */
+void GC_pin_obj_checked(ptr_t p) {
+    unsigned offset = p - GC_nursery_start;
+    unsigned word_offset = BYTES_TO_WORDS(offset);
+    unsigned blockno = (current - GC_nursery_start)/NURSERY_BLOCK_SIZE;
+    while (GC_nursery_map[word_offset] == NURSERY_MAP_NOT_START) {
+       --word_offset;    
+    }
+    if (GC_nursery_map[word_offset] != NURSERY_MAP_PINNED) {
+        GC_nursery_map[word_offset] = NURSERY_MAP_PINNED;
+        ++GC_pinned[blockno];
+        ??Push object at GC_nursery_start + WORDS_TO_BYTES(word_offset)
+        ??onto mark stack. 
+    }
+}
+
+void GC_scan_region_for_nursery(ptr_t low, ptr_t high) {
+#   if CPP_WORDSZ/8 != ALIGNMENT
+      --> fix this
+#   endif
+    word * l = (word *)((word)low + ALIGNMENT - 1 & ~(ALIGNMENT - 1));
+    word * h = (word *)((word)high & ~(ALIGNMENT - 1));
+    word * p;
+    for (p = l; p < h; ++p) {
+       PIN_OBJ(p);
+    }
 }
 
-/* Pin all nursery objects referenced from mark stack. */
-void GC_pin_mark_stack_objects(void) {
-    for each possible pointer current in a mark stack object
-       if (current >= GC_nursery_start && current < GC_nursery_end) {
-           unsigned offset = current - GC_nursery_start;
-           unsigned word_offset = BYTES_TO_WORDS(offset);
-           unsigned blockno = (current - GC_nursery_start)/NURSERY_BLOCK_SIZE;
-           while (GC_nursery_map[word_offset] == NURSERY_MAP_NOT_START) {
-               --word_offset;    
-           }
-           if (GC_nursery_map[word_offset] != NURSERY_MAP_PINNED) {
-               GC_nursery_map[word_offset] = NURSERY_MAP_PINNED;
-               ++GC_pinned[blockno];
-               ??Push object at GC_nursery_start + WORDS_TO_BYTES(word_offset)
-               ??onto stack. 
-           }
+/* Invoke GC_scan_region_for_nursery on ranges that are not excluded. */
+void GC_scan_region_for_nursery_with_exclusions(ptr_t bottom, ptr_t top)
+{
+    struct exclusion * next;
+    ptr_t excl_start;
+
+    while (bottom < top) {
+        next = GC_next_exclusion(bottom);
+       if (0 == next || (excl_start = next -> e_start) >= top) {
+           GC_scan_region_for_nursery(bottom, top);
+           return;
        }
+       if (excl_start > bottom)
+               GC_scan_region_for_nursery(bottom, excl_start);
+       bottom = next -> e_end;
     }
 }
 
+
+void GC_scan_stacks_for_nursery(void) {
+#   ifdef THREADS
+       --> fix this
+#   endif
+#   ifdef STACK_GROWS_DOWN
+      ptr_t stack_low = GC_approx_sp();
+      ptr_t stack_high = GC_stackbottom;
+#   else
+      ptr_t stack_low = GC_stackbottom;
+      ptr_t stack_high = GC_approx_sp();
+#   endif
+    GC_scan_region_for_nursery(stack_low, stack_high);
+#   ifdef IA64
+      GC_scan_region_for_nursery(BACKING_STORE_BASE,
+                                (ptr_t) GC_save_regs_ret_val);
+#   endif
+}
+
+void GC_scan_roots_for_nursery(void) {
+  /* Scan registers.   */
+    /* Direct GC_push_one to call GC_pin_obj instead of marking        */
+    /* and pushing objects.                                    */
+    /* This is a bit ugly, but we don't have to touch the      */
+    /* platform-dependent code.                                        */
+     
+    void (*old_push_proc)(ptr_t) = GC_push_proc;
+    GC_push_proc = GC_pin_obj;
+    GC_push_regs();
+    GC_push_proc = old_push_proc;
+  GC_scan_stacks_for_nursery();
+# ifdef SCAN_STATICS_FOR_NURSERY
+#   if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \
+        && !defined(SRC_M3)
+      GC_remove_tmp_roots();
+      GC_register_dynamic_libraries();
+#   endif
+    /* Mark everything in static data areas                             */
+      for (i = 0; i < n_root_sets; i++) {
+        GC_scan_region_for_nursery_with_exclusions (
+                            GC_static_roots[i].r_start,
+                            GC_static_roots[i].r_end);
+     }
+# endif
+}
+
+/* Array of known rescuing pointers from the heap to the nursery.      */
+ptr_t ** nursery_rescuers;
+
 /* Caller holds allocation lock.       */
 void GC_collect_nursery(void) {
     int i;
     ptr_t scan_ptr = 0;
-    ?? old_mark_stack_top;
     STOP_WORLD;
     for (i = 0; i < GC_nursery_blocks; ++i) GC_pinned[i] = 0;
-    GC_push_all_roots();
-    old_mark_stack_top = GC_mark_stack_top();
-    GC_pin_mark_stack_objects();
+    GC_scan_roots_for_nursery();
+    /* All objects referenced by roots are now pinned.                 */
+    /* Their contents are described by                                 */
+    /* mark stack entries.                                     */
+
+    /* Pin blocks corresponding to valid allocation states.    */
+    /* that probably happens automagically if the allocation   */
+    /* states are kept where we can see them.                  */
+    /* It will take work if static roots are not scanned.      */
+    /* We want to do this both for correctness and to avoid    */
+    /* promoting very young objects.                           */
+
+    /* Somehow capture dirty bits.  Update rescuers array to   */
+    /* reflect newly valid and invalid references from dirty   */
+    /* pages.  Other references should remain valid, since the */
+    /* referents should have been pinned.                      */
+
+    /* Traverse the old object heap.  Pin objects in the       */
+    /* nursery that are ambiguously referenced, copy those     */
+    /* that are unambiguously referenced.                      */
+
+    /* Traverse objects in mark stack.                         */
+    /* If referenced object is in pinned block, add contents   */
+    /* to mark stack.  If referenced object is forwarded,      */
+    /* update pointer.  Otherwise reallocate the object        in the  */
+    /* old heap, copy its contents, and then enqueue its       */
+    /* contents in the mark stack.                             */
     START_WORLD;
 }
 
 /* Initialize an allocation state so that it can be used for   */
 /* allocation.  This implicitly reserves a small section of the        */
-/* nursery for use with his allocator.                         */
+/* nursery for use with this allocator.                                */
+/* Also called to replenish an allocator that has been                 */
+/* exhausted.                                                  */
 void GC_init_copy_alloc_state(GC_copy_alloc_state *)
     unsigned next_block;
     ptr_t block_addr;
@@ -173,3 +308,5 @@ GC_PTR GC_copying_malloc2(GC_copy_descriptor *d, GC_copy_alloc_state *s) {
 
 GC_PTR GC_copying_malloc(GC_copy_descriptor *d) {
 }
+
+#endif /* NURSERY */
index 81f74f3a7e8ac3935e38d50a9a94f73b7f650683..e83b5cacd442bcd2d92bbb52e48f89580ac4e7c1 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -1,6 +1,8 @@
 /*
+ * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
- * Copyright (c) 1996-1997 by Silicon Graphics.  All rights reserved.
+ * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved.
+ * Copyright (c) 1999 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.
@@ -31,7 +33,7 @@
       /* make sure the former gets defined to be the latter if appropriate. */
 #     include <features.h>
 #     if 2 <= __GLIBC__
-#       if 0 == __GLIBC_MINOR__
+#       if 2 == __GLIBC__ && 0 == __GLIBC_MINOR__
          /* glibc 2.1 no longer has sigcontext.h.  But signal.h        */
          /* has the right declaration for glibc 2.1.                   */
 #         include <sigcontext.h>
 # include <signal.h>
 
 /* Blatantly OS dependent routines, except for those that are related  */
-/* dynamic loading.                                                    */
+/* to dynamic loading.                                                 */
 
 # if !defined(THREADS) && !defined(STACKBOTTOM) && defined(HEURISTIC2)
 #   define NEED_FIND_LIMIT
 # endif
 
-# if defined(IRIX_THREADS)
+# if defined(IRIX_THREADS) || defined(HPUX_THREADS)
 #   define NEED_FIND_LIMIT
 # endif
 
@@ -72,7 +74,8 @@
 #   define NEED_FIND_LIMIT
 # endif
 
-# if defined(LINUX) && (defined(POWERPC) || defined(SPARC) || defined(ALPHA))
+# if defined(LINUX) && \
+     (defined(POWERPC) || defined(SPARC) || defined(ALPHA) || defined(IA64))
 #   define NEED_FIND_LIMIT
 # endif
 
 # define OPT_PROT_EXEC 0
 #endif
 
-#if defined(LINUX) && (defined(POWERPC) || defined(SPARC) || defined(ALPHA))
+#if defined(LINUX) && (defined(POWERPC) || defined(SPARC) || defined(ALPHA) \
+                      || defined(IA64))
   /* The I386 case can be handled without a search.  The Alpha case    */
   /* used to be handled differently as well, but the rules changed     */
   /* for recent Linux versions.  This seems to be the easiest way to   */
@@ -497,7 +501,7 @@ ptr_t GC_get_stack_base()
 
 #   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1)
        static struct sigaction old_segv_act;
-#      if defined(_sigargs) /* !Irix6.x */
+#      if defined(_sigargs) || defined(HPUX) /* !Irix6.x */
            static struct sigaction old_bus_act;
 #      endif
 #   else
@@ -525,10 +529,11 @@ ptr_t GC_get_stack_base()
                (void) sigaction(SIGSEGV, &act, 0);
 #        else
                (void) sigaction(SIGSEGV, &act, &old_segv_act);
-#              ifdef _sigargs  /* Irix 5.x, not 6.x */
-                   /* Under 5.x, we may get SIGBUS.                    */
-                   /* Pthreads doesn't exist under 5.x, so we don't    */
-                   /* have to worry in the threads case.               */
+#              if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
+                  || defined(HPUX)
+                   /* Under Irix 5.x or HP/UX, we may get SIGBUS.      */
+                   /* Pthreads doesn't exist under Irix 5.x, so we     */
+                   /* don't have to worry in the threads case.         */
                    (void) sigaction(SIGBUS, &act, &old_bus_act);
 #              endif
 #        endif /* IRIX_THREADS */
@@ -544,7 +549,8 @@ ptr_t GC_get_stack_base()
     {
 #       if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1)
          (void) sigaction(SIGSEGV, &old_segv_act, 0);
-#        ifdef _sigargs        /* Irix 5.x, not 6.x */
+#        if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
+            || defined(HPUX)
              (void) sigaction(SIGBUS, &old_bus_act, 0);
 #        endif
 #       else
@@ -589,6 +595,40 @@ ptr_t GC_get_stack_base()
     }
 # endif
 
+#ifdef LINUX_STACKBOTTOM
+
+# define STAT_SKIP 27   /* Number of fields preceding startstack       */
+                       /* field in /proc/<pid>/stat                    */
+
+  ptr_t GC_linux_stack_base(void)
+  {
+    char buf[50];
+    FILE *f;
+    char c;
+    word result = 0;
+    int i;
+
+    sprintf(buf, "/proc/%d/stat", getpid());
+    f = fopen(buf, "r");
+    if (NULL == f) ABORT("Couldn't open /proc/<pid>/stat");
+    c = getc(f);
+    /* Skip the required number of fields.  This number is hopefully   */
+    /* constant across all Linux implementations.                      */
+      for (i = 0; i < STAT_SKIP; ++i) {
+       while (isspace(c)) c = getc(f);
+       while (!isspace(c)) c = getc(f);
+      }
+    while (isspace(c)) c = getc(f);
+    while (isdigit(c)) {
+      result *= 10;
+      result += c - '0';
+      c = getc(f);
+    }
+    if (result < 0x10000000) ABORT("Absurd stack bottom value");
+    return (ptr_t)result;
+  }
+
+#endif /* LINUX_STACKBOTTOM */
 
 ptr_t GC_get_stack_base()
 {
@@ -610,6 +650,9 @@ ptr_t GC_get_stack_base()
                              & ~STACKBOTTOM_ALIGNMENT_M1);
 #         endif
 #      endif /* HEURISTIC1 */
+#      ifdef LINUX_STACKBOTTOM
+          result = GC_linux_stack_base();
+#      endif
 #      ifdef HEURISTIC2
 #          ifdef STACK_GROWS_DOWN
                result = GC_find_limit((ptr_t)(&dummy), TRUE);
@@ -1443,7 +1486,7 @@ void GC_default_push_other_roots()
 
 # if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
      || defined(IRIX_THREADS) || defined(LINUX_THREADS) \
-     || defined(IRIX_PCR_THREADS)
+     || defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
 
 extern void GC_push_all_stacks();
 
@@ -1570,12 +1613,12 @@ struct hblk *h;
 #   include <sys/syscall.h>
 
 #   define PROTECT(addr, len) \
-         if (mprotect((caddr_t)(addr), (int)(len), \
+         if (mprotect((caddr_t)(addr), (size_t)(len), \
                       PROT_READ | OPT_PROT_EXEC) < 0) { \
            ABORT("mprotect failed"); \
          }
 #   define UNPROTECT(addr, len) \
-         if (mprotect((caddr_t)(addr), (int)(len), \
+         if (mprotect((caddr_t)(addr), (size_t)(len), \
                       PROT_WRITE | PROT_READ | OPT_PROT_EXEC ) < 0) { \
            ABORT("un-mprotect failed"); \
          }
@@ -1604,7 +1647,11 @@ struct hblk *h;
     typedef void (* SIG_PF)();
 #endif
 #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX)
+# ifdef __STDC__
     typedef void (* SIG_PF)(int);
+# else
+    typedef void (* SIG_PF)();
+# endif
 #endif
 #if defined(MSWIN32)
     typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_PF;
@@ -1616,17 +1663,34 @@ struct hblk *h;
     typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
 #endif
 #if defined(SUNOS5SIGS)
-    typedef void (* REAL_SIG_PF)(int, struct siginfo *, void *);
+# ifdef HPUX
+#   define SIGINFO __siginfo
+# else
+#   define SIGINFO siginfo
+# endif
+# ifdef __STDC__
+    typedef void (* REAL_SIG_PF)(int, struct SIGINFO *, void *);
+# else
+    typedef void (* REAL_SIG_PF)();
+# endif
 #endif
 #if defined(LINUX)
 #   include <linux/version.h>
-#   if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA)
+#   if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA) || defined(IA64)
       typedef struct sigcontext s_c;
 #   else
       typedef struct sigcontext_struct s_c;
 #   endif
+#   if defined(ALPHA) || defined(M68K)
+      typedef void (* REAL_SIG_PF)(int, int, s_c *);
+#   else
+#     if defined(IA64)
+        typedef void (* REAL_SIG_PF)(int, siginfo_t *, s_c *);
+#     else
+        typedef void (* REAL_SIG_PF)(int, s_c);
+#     endif
+#   endif
 #   ifdef ALPHA
-    typedef void (* REAL_SIG_PF)(int, int, s_c *);
     /* Retrieve fault address from sigcontext structure by decoding    */
     /* instruction.                                                    */
     char * get_fault_addr(s_c *sc) {
@@ -1638,8 +1702,6 @@ struct hblk *h;
        faultaddr += (word) (((int)instr << 16) >> 16);
        return (char *)faultaddr;
     }
-#   else /* !ALPHA */
-    typedef void (* REAL_SIG_PF)(int, s_c);
 #   endif /* !ALPHA */
 # endif
 
@@ -1675,21 +1737,41 @@ SIG_PF GC_old_segv_handler;     /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #   endif
 # endif
 # if defined(LINUX)
-#   ifdef ALPHA
+#   if defined(ALPHA) || defined(M68K)
       void GC_write_fault_handler(int sig, int code, s_c * sc)
 #   else
-      void GC_write_fault_handler(int sig, s_c sc)
+#     if defined(IA64)
+        void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
+#     else
+        void GC_write_fault_handler(int sig, s_c sc)
+#     endif
 #   endif
 #   define SIG_OK (sig == SIGSEGV)
 #   define CODE_OK TRUE
-       /* Empirically c.trapno == 14, but is that useful?      */
-       /* We assume Intel architecture, so alignment           */
-       /* faults are not possible.                             */
+       /* Empirically c.trapno == 14, on IA32, but is that useful?     */
+       /* Should probably consider alignment issues on other           */
+       /* architectures.                                               */
 # endif
 # if defined(SUNOS5SIGS)
-    void GC_write_fault_handler(int sig, struct siginfo *scp, void * context)
-#   define SIG_OK (sig == SIGSEGV)
-#   define CODE_OK (scp -> si_code == SEGV_ACCERR)
+#  ifdef __STDC__
+    void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
+#  else
+    void GC_write_fault_handler(sig, scp, context)
+    int sig;
+    struct SIGINFO *scp;
+    void * context;
+#  endif
+#   ifdef HPUX
+#     define SIG_OK (sig == SIGSEGV || sig == SIGBUS)
+#     define CODE_OK (scp -> si_code == SEGV_ACCERR) \
+                    || (scp -> si_code == BUS_ADRERR) \
+                    || (scp -> si_code == BUS_UNKNOWN) \
+                    || (scp -> si_code == SEGV_UNKNOWN) \
+                    || (scp -> si_code == BUS_OBJERR)
+#   else
+#     define SIG_OK (sig == SIGSEGV)
+#     define CODE_OK (scp -> si_code == SEGV_ACCERR)
+#   endif
 # endif
 # if defined(MSWIN32)
     LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info)
@@ -1741,7 +1823,15 @@ SIG_PF GC_old_segv_handler;      /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #        ifdef ALPHA
             char * addr = get_fault_addr(sc);
 #        else
+#          ifdef IA64
+             char * addr = si -> si_addr;
+#          else
+#             if defined(POWERPC)
+                char * addr = (char *) (sc.regs->dar);
+#            else
                --> architecture not supported
+#            endif
+#          endif
 #        endif
 #      endif
 #     endif
@@ -1794,10 +1884,14 @@ SIG_PF GC_old_segv_handler;     /* Also old MSWIN32 ACCESS_VIOLATION filter */
                    return;
 #              endif
 #              if defined (LINUX)
-#                  ifdef ALPHA
+#                  if defined(ALPHA) || defined(M68K)
                        (*(REAL_SIG_PF)old_handler) (sig, code, sc);
 #                  else 
+#                    if defined(IA64)
+                       (*(REAL_SIG_PF)old_handler) (sig, si, scp);
+#                    else
                        (*(REAL_SIG_PF)old_handler) (sig, sc);
+#                    endif
 #                  endif
                    return;
 #              endif
@@ -1909,7 +2003,7 @@ void GC_dirty_init()
       }
 #   endif
 #   if defined(SUNOS5SIGS) || defined(IRIX5)
-#     if defined(IRIX_THREADS) || defined(IRIX_PCR_THREADS)
+#     if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS)
        sigaction(SIGSEGV, 0, &oldact);
        sigaction(SIGSEGV, &act, 0);
 #     else
@@ -1935,6 +2029,15 @@ void GC_dirty_init()
          GC_err_printf0("Replaced other SIGSEGV handler\n");
 #       endif
       }
+#     ifdef HPUX
+         sigaction(SIGBUS, &act, &oldact);
+          GC_old_bus_handler = oldact.sa_handler;
+          if (GC_old_segv_handler != SIG_DFL) {
+#           ifdef PRINTSTATS
+             GC_err_printf0("Replaced other SIGBUS handler\n");
+#           endif
+          }
+#     endif
 #    endif
 #   if defined(MSWIN32)
       GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
index 308594696e71490506cb35ff169eba4eabb0bd25..6e0f53bb0589ab2dc82cd981800939146117bf2e 100644 (file)
--- a/reclaim.c
+++ b/reclaim.c
@@ -1,6 +1,8 @@
 /* 
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
- * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
+ * Copyright (c) 1991-1996 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.
  *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -11,7 +13,6 @@
  * provided the above notices are retained, and a notice that the code was
  * modified is included with the above copyright notice.
  */
-/* Boehm, February 15, 1996 2:41 pm PST */
 
 #include <stdio.h>
 #include "gc_priv.h"
@@ -67,6 +68,139 @@ register hdr * hhdr;
     return(TRUE);
 }
 
+/* The following functions sometimes return a DONT_KNOW value. */
+#define DONT_KNOW  2
+
+#ifdef SMALL_CONFIG
+# define GC_block_nearly_full1(hhdr, pat1) DONT_KNOW
+# define GC_block_nearly_full3(hhdr, pat1, pat2) DONT_KNOW
+# define GC_block_nearly_full(hhdr) DONT_KNOW
+#else
+
+/*
+ * Test whether nearly all of the mark words consist of the same
+ * repeating pattern.
+ */
+#define FULL_THRESHOLD (MARK_BITS_SZ/16)
+
+GC_bool GC_block_nearly_full1(hhdr, pat1)
+hdr *hhdr;
+word pat1;
+{
+    unsigned i;
+    unsigned misses = 0;
+    GC_ASSERT((MARK_BITS_SZ & 1) == 0);
+    for (i = 0; i < MARK_BITS_SZ; ++i) {
+       if ((hhdr -> hb_marks[i] | ~pat1) != ONES) {
+           if (++misses > FULL_THRESHOLD) return FALSE;
+       }
+    }
+    return TRUE;
+}
+
+/*
+ * Test whether the same repeating 3 word pattern occurs in nearly
+ * all the mark bit slots.
+ * This is used as a heuristic, so we're a bit sloppy and ignore
+ * the last one or two words.
+ */
+GC_bool GC_block_nearly_full3(hhdr, pat1, pat2, pat3)
+hdr *hhdr;
+word pat1, pat2, pat3;
+{
+    unsigned i;
+    unsigned misses = 0;
+
+    if (MARK_BITS_SZ < 4) {
+      return DONT_KNOW;
+    }
+    for (i = 0; i < MARK_BITS_SZ - 2; i += 3) {
+       if ((hhdr -> hb_marks[i] | ~pat1) != ONES) {
+           if (++misses > FULL_THRESHOLD) return FALSE;
+       }
+       if ((hhdr -> hb_marks[i+1] | ~pat2) != ONES) {
+           if (++misses > FULL_THRESHOLD) return FALSE;
+       }
+       if ((hhdr -> hb_marks[i+2] | ~pat3) != ONES) {
+           if (++misses > FULL_THRESHOLD) return FALSE;
+       }
+    }
+    return TRUE;
+}
+
+/* Check whether a small object block is nearly full by looking at only */
+/* the mark bits.                                                      */
+/* We manually precomputed the mark bit patterns that need to be       */
+/* checked for, and we give up on the ones that are unlikely to occur, */
+/* or have period > 3.                                                 */
+/* This would be a lot easier with a mark bit per object instead of per        */
+/* word, but that would rewuire computing object numbers in the mark   */
+/* loop, which would require different data structures ...             */
+GC_bool GC_block_nearly_full(hhdr)
+hdr *hhdr;
+{
+    int sz = hhdr -> hb_sz;
+
+#   if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
+      return DONT_KNOW;        /* Shouldn't be used in any standard config.    */
+#   endif
+    if (0 != HDR_WORDS) return DONT_KNOW;
+       /* Also shouldn't happen */
+#   if CPP_WORDSZ == 32
+      switch(sz) {
+        case 1:
+         return GC_block_nearly_full1(hhdr, 0xffffffffl);
+       case 2:
+         return GC_block_nearly_full1(hhdr, 0x55555555l);
+       case 4:
+         return GC_block_nearly_full1(hhdr, 0x11111111l);
+       case 6:
+         return GC_block_nearly_full3(hhdr, 0x41041041l,
+                                             0x10410410l,
+                                              0x04104104l);
+       case 8:
+         return GC_block_nearly_full1(hhdr, 0x01010101l);
+       case 12:
+         return GC_block_nearly_full3(hhdr, 0x01001001l,
+                                             0x10010010l,
+                                              0x00100100l);
+       case 16:
+         return GC_block_nearly_full1(hhdr, 0x00010001l);
+       case 32:
+         return GC_block_nearly_full1(hhdr, 0x00000001l);
+       default:
+         return DONT_KNOW;
+      }
+#   endif
+#   if CPP_WORDSZ == 64
+      switch(sz) {
+        case 1:
+         return GC_block_nearly_full1(hhdr, 0xffffffffffffffffl);
+       case 2:
+         return GC_block_nearly_full1(hhdr, 0x5555555555555555l);
+       case 4:
+         return GC_block_nearly_full1(hhdr, 0x1111111111111111l);
+       case 6:
+         return GC_block_nearly_full3(hhdr, 0x1041041041041041l,
+                                              0x4104104104104104l,
+                                                0x0410410410410410l);
+       case 8:
+         return GC_block_nearly_full1(hhdr, 0x0101010101010101l);
+       case 12:
+         return GC_block_nearly_full3(hhdr, 0x1001001001001001l,
+                                              0x0100100100100100l,
+                                                0x0010010010010010l);
+       case 16:
+         return GC_block_nearly_full1(hhdr, 0x0001000100010001l);
+       case 32:
+         return GC_block_nearly_full1(hhdr, 0x0000000100000001l);
+       default:
+         return DONT_KNOW;
+      }
+#   endif
+}
+#endif /* !SMALL_CONFIG */
+
 # ifdef GATHERSTATS
 #   define INCR_WORDS(sz) n_words_found += (sz)
 # else
@@ -448,10 +582,11 @@ register struct hblk *hbp;        /* ptr to current heap block            */
 int report_if_found;           /* Abort if a reclaimable object is found */
 {
     hdr * hhdr;
-    register word sz;          /* size of objects in current block     */
-    register struct obj_kind * ok;
-    register ptr_t * flh;
-    register int kind;
+    word sz;           /* size of objects in current block     */
+    struct obj_kind * ok;
+    ptr_t * flh;
+    int kind;
+    GC_bool full;
     
     hhdr = HDR(hbp);
     sz = hhdr -> hb_sz;
@@ -459,7 +594,6 @@ int report_if_found;                /* Abort if a reclaimable object is found */
     kind = hhdr -> hb_obj_kind;
     ok = &GC_obj_kinds[kind];
     flh = &(ok -> ok_freelist[sz]);
-    GC_write_hint(hbp);
 
     if (report_if_found) {
        GC_reclaim_check(hbp, hhdr, sz);
@@ -467,16 +601,29 @@ int report_if_found;              /* Abort if a reclaimable object is found */
       switch(sz) {
 #      ifndef SMALL_CONFIG
         case 1:
+           full = GC_block_nearly_full1(hhdr, 0xffffffffl);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
+           /* In the DONT_KNOW case, we let reclaim fault.     */
             *flh = GC_reclaim1(hbp, hhdr, *flh);
             break;
         case 2:
+           full = GC_block_nearly_full1(hhdr, 0x55555555l);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim_clear2(hbp, hhdr, *flh);
             break;
         case 4:
+           full = GC_block_nearly_full1(hhdr, 0x11111111l);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim_clear4(hbp, hhdr, *flh);
             break;
 #      endif
         default:
+           full = GC_block_nearly_full(hhdr);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim_clear(hbp, hhdr, sz, *flh);
             break;
       }
@@ -484,20 +631,33 @@ int report_if_found;              /* Abort if a reclaimable object is found */
       switch(sz) {
 #      ifndef SMALL_CONFIG
         case 1:
+           full = GC_block_nearly_full1(hhdr, 0xffffffffl);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim1(hbp, hhdr, *flh);
             break;
         case 2:
+           full = GC_block_nearly_full1(hhdr, 0x55555555l);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim_uninit2(hbp, hhdr, *flh);
             break;
         case 4:
+           full = GC_block_nearly_full1(hhdr, 0x11111111l);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim_uninit4(hbp, hhdr, *flh);
             break;
 #      endif
         default:
+           full = GC_block_nearly_full(hhdr);
+           if (TRUE == full) goto out;
+           if (FALSE == full) GC_write_hint(hbp);
             *flh = GC_reclaim_uninit(hbp, hhdr, sz, *flh);
             break;
       }
     } 
+out:
     if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(hhdr);
 }
 
diff --git a/test.c b/test.c
index b65632c95ec482deaa02d6bdff217db59a4e28d2..43b09010f8017ac7abc27ccb8a84de6a4776ce79 100644 (file)
--- a/test.c
+++ b/test.c
@@ -45,7 +45,7 @@
 #   include <synch.h>
 # endif
 
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
 #   include <pthread.h>
 # endif
 
@@ -53,9 +53,6 @@
 #   include <process.h>
     static CRITICAL_SECTION incr_cs;
 # endif
-# if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS)
-#   define THREADS
-# endif
 
 # ifdef AMIGA
    long __stack = 200000;
@@ -281,7 +278,7 @@ struct {
 }
 
 # if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
-     || defined(SOLARIS_PTHREADS)
+     || defined(SOLARIS_PTHREADS) || defined(HPUX_THREADS)
     void fork_a_thread()
     {
       pthread_t t;
@@ -453,7 +450,7 @@ VOLATILE int dropped_something = 0;
     static mutex_t incr_lock;
     mutex_lock(&incr_lock);
 # endif
-# if  defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if  defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
     static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
     pthread_mutex_lock(&incr_lock);
 # endif
@@ -471,7 +468,7 @@ VOLATILE int dropped_something = 0;
 # ifdef SOLARIS_THREADS
     mutex_unlock(&incr_lock);
 # endif
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
     pthread_mutex_unlock(&incr_lock);
 # endif
 # ifdef WIN32_THREADS
@@ -532,7 +529,8 @@ int n;
            static mutex_t incr_lock;
            mutex_lock(&incr_lock);
 #        endif
-#         if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#         if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+            || defined(HPUX_THREADS)
             static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
             pthread_mutex_lock(&incr_lock);
 #         endif
@@ -548,7 +546,8 @@ int n;
 #        ifdef SOLARIS_THREADS
            mutex_unlock(&incr_lock);
 #        endif
-#        if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#        if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+            || defined(HPUX_THREADS)
            pthread_mutex_unlock(&incr_lock);
 #        endif
 #         ifdef WIN32_THREADS
@@ -644,7 +643,7 @@ void * alloc8bytes()
 #else
 
 # if defined(_SOLARIS_PTHREADS) || defined(IRIX_THREADS) \
-     || defined(LINUX_THREADS)
+     || defined(LINUX_THREADS) || defined(HPUX_THREADS)
 pthread_key_t fl_key;
 
 void * alloc8bytes()
@@ -857,6 +856,7 @@ void run_one_test()
        (void)GC_printf0("GC_malloc_uncollectable(0) failed\n");
            FAIL;
     }
+    GC_FREE(0);
     GC_is_valid_displacement_print_proc = fail_proc1;
     GC_is_visible_print_proc = fail_proc1;
     x = GC_malloc(16);
@@ -879,7 +879,7 @@ void run_one_test()
        FAIL;
     }
     if (!TEST_FAIL_COUNT(1)) {
-#      if!(defined(RS6000) || defined(POWERPC))
+#      if!(defined(RS6000) || defined(POWERPC) || defined(IA64))
          /* ON RS6000s function pointers point to a descriptor in the  */
          /* data segment, so there should have been no failures.       */
          (void)GC_printf0("GC_is_visible produced wrong failure indication\n");
@@ -1030,7 +1030,8 @@ void SetMinimumStack(long minSize)
 
 
 #if !defined(PCR) && !defined(SOLARIS_THREADS) && !defined(WIN32_THREADS) \
-  && !defined(IRIX_THREADS) && !defined(LINUX_THREADS) || defined(LINT)
+  && !defined(IRIX_THREADS) && !defined(LINUX_THREADS) \
+  && !defined(HPUX_THREADS) || defined(LINT)
 #ifdef MSWIN32
   int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n)
 #else
@@ -1161,7 +1162,8 @@ test()
 }
 #endif
 
-#if defined(SOLARIS_THREADS) || defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#if defined(SOLARIS_THREADS) || defined(IRIX_THREADS) \
+ || defined(HPUX_THREADS) || defined(LINUX_THREADS)
 void * thr_run_one_test(void * arg)
 {
     run_one_test();
@@ -1222,7 +1224,7 @@ main()
        *((volatile char *)&code - 1024*1024) = 0;      /* Require 1 Mb */
 #   endif /* IRIX_THREADS */
     pthread_attr_init(&attr);
-#   ifdef IRIX_THREADS
+#   if defined(IRIX_THREADS) || defined(HPUX_THREADS)
        pthread_attr_setstacksize(&attr, 1000000);
 #   endif
     n_tests = 0;
@@ -1232,7 +1234,7 @@ main()
        (void) GC_printf0("Emulating dirty bits with mprotect/signals\n");
 #   endif
     (void) GC_set_warn_proc(warn_proc);
-    if (pthread_key_create(&fl_key, 0) != 0) {
+    if ((code = pthread_key_create(&fl_key, 0)) != 0) {
         (void)GC_printf1("Key creation failed %lu\n", (unsigned long)code);
        FAIL;
     }
@@ -1260,4 +1262,4 @@ main()
     return(0);
 }
 #endif /* pthreads */
-#endif /* SOLARIS_THREADS || IRIX_THREADS || LINUX_THREADS */
+#endif /* SOLARIS_THREADS || IRIX_THREADS || LINUX_THREADS || HPUX_THREADS */
index 4a0a6cfcd4230d0e29458f85940e477405c6bdeb..df4eb77bb1da64abd258061985371e7ba44227c8 100644 (file)
@@ -6,6 +6,9 @@ int main()
 #   if defined(IRIX_THREADS) || defined(LINUX_THREADS)
        printf("-lpthread\n");
 #   endif
+#   if defined(HPUX_THREADS)
+       printf("-lpthread -lrt\n");
+#   endif
 #   ifdef SOLARIS_THREADS
         printf("-lthread -ldl\n");
 #   endif
index 97ac5f5e63bb693bed98b98412738e6757ea18a9..df0770c9b04c534d5626a65abcd66a1b1b368940 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
 #define GC_VERSION_MAJOR 5
 #define GC_VERSION_MINOR 0
-#define GC_ALPHA_VERSION 3
+#define GC_ALPHA_VERSION 4
 
 #   define GC_NOT_ALPHA 0xff