diff options
author | bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-02-12 04:37:57 +0000 |
---|---|---|
committer | bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-02-12 04:37:57 +0000 |
commit | 0cc01484c3f8c9ec4fec760501aec318bc199adf (patch) | |
tree | cef3197531d988920cbff060bdc10742baf06d01 | |
parent | b6c37935d39c0aadd3d6eefb9e09c455c6cbd0a5 (diff) | |
download | gcc-0cc01484c3f8c9ec4fec760501aec318bc199adf.tar.gz |
Imported GC 6.1 Alpha 3. Finally.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49698 138bc75d-0d04-0410-961f-82ee72b054a4
40 files changed, 1285 insertions, 510 deletions
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 8512374d017..8f724c280c0 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,6 +1,10 @@ +2002-02-12 Bryce McKinlay <bryce@waitaki.otago.ac.nz> + + Imported GC 6.1 Alpha 3. + 2001-02-11 Adam Megacz <adam@xwt.org - * gcc/boehm-gc/configure.in: support for win32, saner + * gcc/boehm-gc/configure.in: support for win32, saner cross-compile options 2001-02-08 Anthony Green <green@redhat.com> @@ -16,13 +20,13 @@ 2002-02-06 Adam Megacz <adam@xwt.org> - * boehm-gc/include/gc.h: (GC_CreateThread) This function is - now exposed on all Win32 platforms. - * boehm-gc/win32_threads.c: (GC_CreateThread) This now - compiles on Win32; it invokes CreateThread() if GC is built - as a DLL; otherwise it registers the thread. - * boehm-gc/misc.c (GC_init): Initialize GC_allocate_ml in case - libgcjgc was not built as a DLL. + * boehm-gc/include/gc.h: (GC_CreateThread) This function is + now exposed on all Win32 platforms. + * boehm-gc/win32_threads.c: (GC_CreateThread) This now + compiles on Win32; it invokes CreateThread() if GC is built + as a DLL; otherwise it registers the thread. + * boehm-gc/misc.c (GC_init): Initialize GC_allocate_ml in case + libgcjgc was not built as a DLL. 2002-02-01 Adam Megacz <adam@xwt.org> diff --git a/boehm-gc/Makefile.am b/boehm-gc/Makefile.am index 736c2b51b96..40970729f44 100644 --- a/boehm-gc/Makefile.am +++ b/boehm-gc/Makefile.am @@ -6,8 +6,6 @@ AUTOMAKE_OPTIONS = cygnus -SUBDIRS = include - # Multilib support variables. MULTISRCTOP = MULTIBUILDTOP = @@ -31,7 +29,8 @@ libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \ dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \ linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ -solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c +solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \ +backgraph.c # Include THREADLIBS here to ensure that the correct versions of # linuxthread semaphore functions get linked: diff --git a/boehm-gc/Makefile.direct b/boehm-gc/Makefile.direct index 84a7dd3d63e..af6192ebc45 100644 --- a/boehm-gc/Makefile.direct +++ b/boehm-gc/Makefile.direct @@ -10,20 +10,13 @@ # c++ interface to gc.a # cord/de - builds dumb editor based on cords. ABI_FLAG= -# ABI_FLAG should be the cc flag that specifies the ABI. On most -# platforms this will be the empty string. Possible values: -# +DD64 for 64-bit executable on HP/UX. -# -n32, -n64, -o32 for SGI/MIPS ABIs. - -AS_ABI_FLAG=$(ABI_FLAG) -# ABI flag for assembler. On HP/UX this is +A64 for 64 bit -# executables. - CC=cc $(ABI_FLAG) CXX=g++ $(ABI_FLAG) -AS=as $(AS_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. +# Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64) +# if you use something other than the default ABI on your machine. # Redefining srcdir allows object code for the nonPCR version of the collector # to be generated in different directories. @@ -61,15 +54,12 @@ HOSTCFLAGS=$(CFLAGS) # gc.h before performing thr_ or dl* or GC_ operations.) # Must also define -D_REENTRANT. # -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads. -# (Internally this define GC_SOLARIS_THREADS as well.) +# Define SOLARIS_THREADS as well. # -DGC_IRIX_THREADS enables support for Irix pthreads. See README.irix. # -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads. # Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp. # -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads. # see README.linux. -D_REENTRANT may also be required. -# -DGC_OSF1_THREADS enables support for Tru64 pthreads. Untested. -# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. Untested. -# Appeared to run into some underlying thread problems. # -DALL_INTERIOR_POINTERS allows all pointers to the interior # of objects to be recognized. (See gc_priv.h for consequences.) # Alternatively, GC_all_interior_pointers can be set at process @@ -207,8 +197,8 @@ HOSTCFLAGS=$(CFLAGS) # 15% or so. # -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style # prefetch instructions. Same restrictions as USE_I686_PREFETCH. -# Minimally tested. Didn't appear to be an obvious win on a K6-2/500. -# -DGC_USE_LD_WRAP in combination with the old flags listed in README.linux +# UNTESTED!! +# -DGC_USE_LD_WRAP in combination with the gld flags listed in README.linux # causes the collector some system and pthread calls in a more transparent # fashion than the usual macro-based approach. Requires GNU ld, and # currently probably works only with Linux. @@ -266,8 +256,7 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \ include/gc_local_alloc.h include/private/dbg_mlc.h \ include/private/specific.h powerpc_macosx_mach_dep.s \ include/leak_detector.h include/gc_amiga_redirects.h \ - include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \ - $(CORD_SRCS) + include/gc_pthread_redirects.h $(CORD_SRCS) DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ doc/README.amiga doc/README.cords doc/debugging.html \ diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in index 5c5da8418a2..4460d67289b 100644 --- a/boehm-gc/Makefile.in +++ b/boehm-gc/Makefile.in @@ -96,8 +96,6 @@ target_all = @target_all@ AUTOMAKE_OPTIONS = cygnus -SUBDIRS = include - # Multilib support variables. MULTISRCTOP = MULTIBUILDTOP = @@ -105,13 +103,18 @@ MULTIDIRS = MULTISUBDIR = MULTIDO = true MULTICLEAN = true -@USE_LIBDIR_TRUE@toolexeclibdir = $(libdir)$(MULTISUBDIR) -@USE_LIBDIR_FALSE@toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR) -@USE_LIBDIR_FALSE@toolexecdir = $(exec_prefix)/$(target_alias) +@USE_LIBDIR_TRUE@toolexeclibdir = @USE_LIBDIR_TRUE@$(libdir)$(MULTISUBDIR) +@USE_LIBDIR_FALSE@toolexeclibdir = @USE_LIBDIR_FALSE@$(toolexecdir)/lib$(MULTISUBDIR) +@USE_LIBDIR_FALSE@toolexecdir = @USE_LIBDIR_FALSE@$(exec_prefix)/$(target_alias) toolexeclib_LTLIBRARIES = $(target_all) EXTRA_LTLIBRARIES = libgcjgc.la -libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c +libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \ +dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \ +linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \ +obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ +solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \ +backgraph.c # Include THREADLIBS here to ensure that the correct versions of @@ -120,7 +123,10 @@ libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) libgcjgc_la_DEPENDENCIES = @addobjs@ libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir) -EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s +EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s \ +mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \ +rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s \ +sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s AM_CXXFLAGS = @GC_CFLAGS@ @@ -138,14 +144,52 @@ TESTS = gctest all_objs = @addobjs@ $(libgcjgc_la_OBJECTS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@ # Work around what appears to be a GNU make bug handling MAKEFLAGS # values defined in terms of make variables, as is the case for CC and # friends when we are called from the top level Makefile. -AM_MAKEFLAGS = "AR_FLAGS=$(AR_FLAGS)" "CC_FOR_BUILD=$(CC_FOR_BUILD)" "CFLAGS=$(CFLAGS)" "CXXFLAGS=$(CXXFLAGS)" "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" "INSTALL=$(INSTALL)" "INSTALL_DATA=$(INSTALL_DATA)" "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" "LDFLAGS=$(LDFLAGS)" "LIBCFLAGS=$(LIBCFLAGS)" "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" "MAKE=$(MAKE)" "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" "PICFLAG=$(PICFLAG)" "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" "SHELL=$(SHELL)" "EXPECT=$(EXPECT)" "RUNTEST=$(RUNTEST)" "RUNTESTFLAGS=$(RUNTESTFLAGS)" "exec_prefix=$(exec_prefix)" "infodir=$(infodir)" "libdir=$(libdir)" "prefix=$(prefix)" "tooldir=$(tooldir)" "AR=$(AR)" "AS=$(AS)" "CC=$(CC)" "CXX=$(CXX)" "LD=$(LD)" "LIBCFLAGS=$(LIBCFLAGS)" "NM=$(NM)" "PICFLAG=$(PICFLAG)" "RANLIB=$(RANLIB)" "DESTDIR=$(DESTDIR)" +AM_MAKEFLAGS = \ + "AR_FLAGS=$(AR_FLAGS)" \ + "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ + "CFLAGS=$(CFLAGS)" \ + "CXXFLAGS=$(CXXFLAGS)" \ + "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ + "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ + "INSTALL=$(INSTALL)" \ + "INSTALL_DATA=$(INSTALL_DATA)" \ + "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ + "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ + "LDFLAGS=$(LDFLAGS)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ + "MAKE=$(MAKE)" \ + "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ + "PICFLAG=$(PICFLAG)" \ + "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ + "SHELL=$(SHELL)" \ + "EXPECT=$(EXPECT)" \ + "RUNTEST=$(RUNTEST)" \ + "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ + "exec_prefix=$(exec_prefix)" \ + "infodir=$(infodir)" \ + "libdir=$(libdir)" \ + "prefix=$(prefix)" \ + "tooldir=$(tooldir)" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "CC=$(CC)" \ + "CXX=$(CXX)" \ + "LD=$(LD)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "NM=$(NM)" \ + "PICFLAG=$(PICFLAG)" \ + "RANLIB=$(RANLIB)" \ + "DESTDIR=$(DESTDIR)" CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host @@ -165,7 +209,7 @@ dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \ irix_threads.lo linux_threads.lo malloc.lo mallocx.lo mark.lo \ mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo \ ptr_chck.lo real_malloc.lo reclaim.lo solaris_pthreads.lo \ -solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo +solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo backgraph.lo check_PROGRAMS = gctest$(EXEEXT) gctest_DEPENDENCIES = ./libgcjgc.la CFLAGS = @CFLAGS@ @@ -283,61 +327,6 @@ gctest$(EXEEXT): $(gctest_OBJECTS) $(gctest_DEPENDENCIES) @rm -f gctest$(EXEEXT) $(LINK) $(gctest_LDFLAGS) $(gctest_OBJECTS) $(gctest_LDADD) $(LIBS) -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. - -@SET_MAKE@ - -all-recursive install-data-recursive install-exec-recursive \ -installdirs-recursive install-recursive uninstall-recursive install-info-recursive \ -check-recursive installcheck-recursive info-recursive dvi-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ - rev="$$subdir $$rev"; \ - test "$$subdir" = "." && dot_seen=yes; \ - done; \ - test "$$dot_seen" = "no" && rev=". $$rev"; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done - tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) @@ -348,14 +337,9 @@ ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ @@ -420,16 +404,6 @@ distdir: $(DISTFILES) || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done - for subdir in $(SUBDIRS); do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ - || exit 1; \ - fi; \ - done check-TESTS: $(TESTS) @failed=0; all=0; \ srcdir=$(srcdir); export srcdir; \ @@ -456,33 +430,32 @@ check-TESTS: $(TESTS) echo "$$dashes"; \ test "$$failed" -eq 0 info-am: -info: info-recursive +info: info-am dvi-am: -dvi: dvi-recursive +dvi: dvi-am check-am: $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-recursive +check: check-am installcheck-am: -installcheck: installcheck-recursive +installcheck: installcheck-am install-info-am: -install-info: install-info-recursive +install-info: install-info-am install-exec-am: install-toolexeclibLTLIBRARIES -install-exec: install-exec-recursive +install-exec: install-exec-am install-data-am: -install-data: install-data-recursive +install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-recursive +install: install-am uninstall-am: uninstall-toolexeclibLTLIBRARIES -uninstall: uninstall-recursive +uninstall: uninstall-am all-am: Makefile $(LTLIBRARIES) -all-redirect: all-recursive +all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: installdirs-recursive -installdirs-am: +installdirs: $(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) @@ -499,20 +472,20 @@ mostlyclean-am: mostlyclean-toolexeclibLTLIBRARIES mostlyclean-compile \ mostlyclean-libtool mostlyclean-checkPROGRAMS \ mostlyclean-tags mostlyclean-generic -mostlyclean: mostlyclean-recursive +mostlyclean: mostlyclean-am clean-am: clean-toolexeclibLTLIBRARIES clean-compile clean-libtool \ clean-checkPROGRAMS clean-tags clean-generic \ mostlyclean-am -clean: clean-recursive +clean: clean-am distclean-am: distclean-toolexeclibLTLIBRARIES distclean-compile \ distclean-libtool distclean-checkPROGRAMS \ distclean-tags distclean-generic clean-am -rm -f libtool -distclean: distclean-recursive +distclean: distclean-am -rm -f config.status maintainer-clean-am: maintainer-clean-toolexeclibLTLIBRARIES \ @@ -522,7 +495,7 @@ maintainer-clean-am: maintainer-clean-toolexeclibLTLIBRARIES \ @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." -maintainer-clean: maintainer-clean-recursive +maintainer-clean: maintainer-clean-am -rm -f config.status .PHONY: mostlyclean-toolexeclibLTLIBRARIES \ @@ -533,19 +506,13 @@ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile mostlyclean-libtool distclean-libtool \ clean-libtool maintainer-clean-libtool mostlyclean-checkPROGRAMS \ distclean-checkPROGRAMS clean-checkPROGRAMS \ -maintainer-clean-checkPROGRAMS install-data-recursive \ -uninstall-data-recursive install-exec-recursive \ -uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ -all-recursive check-recursive installcheck-recursive info-recursive \ -dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ -maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir check-TESTS \ -info-am info dvi-am dvi check check-am installcheck-am installcheck \ -install-info-am install-info install-exec-am install-exec \ -install-data-am install-data install-am install uninstall-am uninstall \ -all-redirect all-am all installdirs-am installdirs mostlyclean-generic \ -distclean-generic clean-generic maintainer-clean-generic clean \ -mostlyclean distclean maintainer-clean +maintainer-clean-checkPROGRAMS tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir check-TESTS info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-info-am \ +install-info install-exec-am install-exec install-data-am install-data \ +install-am install uninstall-am uninstall all-redirect all-am all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean # The following hack produces a warning from automake, but we need it in order # to build a file from a subdirectory. FIXME. diff --git a/boehm-gc/allchblk.c b/boehm-gc/allchblk.c index 06582ec792e..3da58c4ca0c 100644 --- a/boehm-gc/allchblk.c +++ b/boehm-gc/allchblk.c @@ -86,7 +86,6 @@ word blocks_needed; } -# define HBLK_IS_FREE(hdr) ((hdr) -> hb_map == GC_invalid_map) # define PHDR(hhdr) HDR(hhdr -> hb_prev) # define NHDR(hhdr) HDR(hhdr -> hb_next) @@ -719,9 +718,6 @@ int n; if (0 == hbp) return 0; - /* Notify virtual dirty bit implementation that we are about to write. */ - GC_write_hint(hbp); - /* Add it to map of valid blocks */ if (!GC_install_counts(hbp, (word)size_needed)) return(0); /* This leaks memory under very rare conditions. */ @@ -731,6 +727,11 @@ int n; GC_remove_counts(hbp, (word)size_needed); return(0); /* ditto */ } + + /* Notify virtual dirty bit implementation that we are about to write. */ + /* Ensure that pointerfree objects are not protected if it's avoidable. */ + GC_remove_protection(hbp, divHBLKSZ(size_needed), + (hhdr -> hb_descr == 0) /* pointer-free */); /* We just successfully allocated a block. Restart count of */ /* consecutive failures. */ diff --git a/boehm-gc/alloc.c b/boehm-gc/alloc.c index 1664e4a4df5..8a413b275f8 100644 --- a/boehm-gc/alloc.c +++ b/boehm-gc/alloc.c @@ -78,7 +78,7 @@ char * GC_copyright[] = {"Copyright 1988,1989 Hans-J. Boehm and Alan J. Demers ", "Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. ", "Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. ", -"Copyright (c) 1999-2000 by Hewlett-Packard Company. All rights reserved. ", +"Copyright (c) 1999-2001 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.", "See source code for details." }; @@ -97,13 +97,17 @@ word GC_free_space_divisor = 3; extern GC_bool GC_collection_in_progress(); /* Collection is in progress, or was abandoned. */ +extern GC_bool GC_print_back_height; + int GC_never_stop_func GC_PROTO((void)) { return(0); } +unsigned long GC_time_limit = TIME_LIMIT; + CLOCK_TYPE GC_start_time; /* Time at which we stopped world. */ /* used only in GC_timeout_stop_func. */ int GC_n_attempts = 0; /* Number of attempts at finishing */ - /* collection within TIME_LIMIT */ + /* collection within GC_time_limit. */ #if defined(SMALL_CONFIG) || defined(NO_CLOCK) # define GC_timeout_stop_func GC_never_stop_func @@ -118,7 +122,7 @@ int GC_n_attempts = 0; /* Number of attempts at finishing */ #ifndef NO_CLOCK GET_TIME(current_time); time_diff = MS_TIME_DIFF(current_time,GC_start_time); - if (time_diff >= TIME_LIMIT) { + if (time_diff >= GC_time_limit) { # ifdef CONDPRINT if (GC_print_stats) { GC_printf0("Abandoning stopped marking after "); @@ -277,9 +281,10 @@ void GC_maybe_gc() /* If we run out of time, this turns into */ /* incremental marking. */ # ifndef NO_CLOCK - GET_TIME(GC_start_time); + if (GC_time_limit != GC_TIME_UNLIMITED) { GET_TIME(GC_start_time); } # endif - if (GC_stopped_mark(GC_timeout_stop_func)) { + if (GC_stopped_mark(GC_time_limit == GC_TIME_UNLIMITED? + GC_never_stop_func : GC_timeout_stop_func)) { # ifdef SAVE_CALL_CHAIN GC_save_callers(GC_last_stack); # endif @@ -391,7 +396,8 @@ int n; # ifdef PARALLEL_MARK GC_wait_for_reclaim(); # endif - if (GC_n_attempts < MAX_PRIOR_ATTEMPTS) { + if (GC_n_attempts < MAX_PRIOR_ATTEMPTS + && GC_time_limit != GC_TIME_UNLIMITED) { GET_TIME(GC_start_time); if (!GC_stopped_mark(GC_timeout_stop_func)) { GC_n_attempts++; @@ -436,7 +442,7 @@ GC_stop_func stop_func; { register int i; int dummy; -# ifdef PRINTTIMES +# if defined(PRINTTIMES) || defined(CONDPRINT) CLOCK_TYPE start_time, current_time; # endif @@ -444,6 +450,9 @@ GC_stop_func stop_func; # ifdef PRINTTIMES GET_TIME(start_time); # endif +# if defined(CONDPRINT) && !defined(PRINTTIMES) + if (GC_print_stats) GET_TIME(start_time); +# endif # ifdef CONDPRINT if (GC_print_stats) { GC_printf1("--> Marking for collection %lu ", @@ -453,6 +462,11 @@ GC_stop_func stop_func; (unsigned long) WORDS_TO_BYTES(GC_words_wasted)); } # endif +# ifdef MAKE_BACK_GRAPH + if (GC_print_back_height) { + GC_build_back_graph(); + } +# endif /* Mark from all roots. */ /* Minimize junk left in my registers and on the stack */ @@ -506,6 +520,14 @@ GC_stop_func stop_func; GET_TIME(current_time); GC_printf1("World-stopped marking took %lu msecs\n", MS_TIME_DIFF(current_time,start_time)); +# else +# ifdef CONDPRINT + if (GC_print_stats) { + GET_TIME(current_time); + GC_printf1("World-stopped marking took %lu msecs\n", + MS_TIME_DIFF(current_time,start_time)); + } +# endif # endif START_WORLD(); return(TRUE); @@ -612,6 +634,17 @@ void GC_finish_collection() GET_TIME(finalize_time); # endif + if (GC_print_back_height) { +# ifdef MAKE_BACK_GRAPH + GC_traverse_back_graph(); +# else +# ifndef SMALL_CONFIG + GC_err_printf0("Back height not available: " + "Rebuild collector with -DMAKE_BACK_GRAPH\n"); +# endif +# endif + } + /* Clear free list mark bits, in case they got accidentally marked */ /* (or GC_find_leak is set and they were intentionally marked). */ /* Also subtract memory remaining from GC_mem_found count. */ diff --git a/boehm-gc/config.guess b/boehm-gc/config.guess index 297e5c30f41..aa6ea3f6766 100755 --- a/boehm-gc/config.guess +++ b/boehm-gc/config.guess @@ -1,9 +1,9 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. -timestamp='2001-10-05' +timestamp='2002-01-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ timestamp='2001-10-05' # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. -# Originally written by Per Bothner <bothner@cygnus.com>. +# Originally written by Per Bothner <per@bothner.com>. # Please send patches to <config-patches@gnu.org>. Submit a context # diff and a properly formatted ChangeLog entry. # @@ -135,23 +135,21 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. - # Determine the machine/vendor (is the vendor relevant). - case "${UNAME_MACHINE}" in - amiga) machine=m68k-unknown ;; - arm32) machine=arm-unknown ;; - atari*) machine=m68k-atari ;; - sun3*) machine=m68k-sun ;; - mac68k) machine=m68k-apple ;; - macppc) machine=powerpc-apple ;; - hp3[0-9][05]) machine=m68k-hp ;; - ibmrt|romp-ibm) machine=romp-ibm ;; - sparc*) machine=`uname -p`-unknown ;; - *) machine=${UNAME_MACHINE}-unknown ;; + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p) 2>/dev/null` || \ + UNAME_MACHINE_ARCH=unknown + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. - case "${UNAME_MACHINE}" in - i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null @@ -291,6 +289,9 @@ EOF *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; @@ -736,6 +737,9 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -767,10 +771,24 @@ EOF echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) - case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in - big) echo mips-unknown-linux-gnu && exit 0 ;; - little) echo mipsel-unknown-linux-gnu && exit 0 ;; - esac + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu @@ -843,32 +861,25 @@ EOF esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build - cat >$dummy.c <<EOF -#include <features.h> -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __ELF__ -# ifdef __GLIBC__ -# if __GLIBC__ >= 2 - printf ("%s-pc-linux-gnu\n", argv[1]); -# else - printf ("%s-pc-linux-gnulibc1\n", argv[1]); -# endif -# else - printf ("%s-pc-linux-gnulibc1\n", argv[1]); -# endif -#else - printf ("%s-pc-linux-gnuaout\n", argv[1]); -#endif - return 0; -} + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + LIBC=gnuaout + #endif EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) @@ -947,7 +958,7 @@ EOF exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` @@ -1056,7 +1067,7 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; - NSR-[KW]:NONSTOP_KERNEL:*:*) + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) diff --git a/boehm-gc/config.sub b/boehm-gc/config.sub index 28426bb8fa0..16573348b81 100755 --- a/boehm-gc/config.sub +++ b/boehm-gc/config.sub @@ -1,6 +1,10 @@ #! /bin/sh -# Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-01-02' + # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. @@ -25,6 +29,9 @@ # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. @@ -45,30 +52,73 @@ # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -if [ x$1 = x ] -then - echo Configuration name missing. 1>&2 - echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 - echo "or $0 ALIAS" 1>&2 - echo where ALIAS is a recognized configuration type. 1>&2 - exit 1 -fi +me=`echo "$0" | sed -e 's,.*/,,'` -# First pass through any local machine types. -case $1 in - *local*) - echo $1 - exit 0 - ;; - *) - ;; +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - linux-gnu*) + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -94,7 +144,7 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple) + -apple | -axis) os= basic_machine=$1 ;; @@ -108,6 +158,14 @@ case $os in os=-vxworks basic_machine=$1 ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; @@ -166,27 +224,50 @@ esac case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. - tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ - | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ - | 580 | i960 | h8300 \ - | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ - | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ - | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ - | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ - | mips64orion | mips64orionel | mipstx39 | mipstx39el \ - | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ - | mips64vr5000 | miprs64vr5000el | mcore \ - | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ - | thumb | d10v | fr30) + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle \ + | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) basic_machine=$basic_machine-unknown ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. - i[34567]86) + i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. @@ -195,24 +276,45 @@ case $basic_machine in exit 1 ;; # Recognize the basic CPU types with company name. - # FIXME: clean up the formatting here. - vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ - | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ - | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ - | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ - | xmp-* | ymp-* \ - | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ - | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ - | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ - | clipper-* | orion-* \ - | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ - | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ - | mipstx39-* | mipstx39el-* | mcore-* \ - | f301-* | armv*-* | t3e-* \ - | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ - | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* ) + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cray2-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \ + | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -249,14 +351,14 @@ case $basic_machine in os=-sysv ;; amiga | amiga-*) - basic_machine=m68k-cbm + basic_machine=m68k-unknown ;; amigaos | amigados) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-sysv4 ;; apollo68) @@ -303,19 +405,30 @@ case $basic_machine in basic_machine=cray2-cray os=-unicos ;; - [ctj]90-cray) - basic_machine=c90-cray + [cjt]90) + basic_machine=${basic_machine}-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola @@ -357,6 +470,10 @@ case $basic_machine in basic_machine=tron-gmicro os=-sysv ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -432,19 +549,19 @@ case $basic_machine in basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? - i[34567]86v32) + i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; - i[34567]86v4*) + i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; - i[34567]86v) + i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; - i[34567]86sol2) + i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; @@ -456,17 +573,6 @@ case $basic_machine in basic_machine=i386-unknown os=-vsta ;; - i386-go32 | go32) - basic_machine=i386-unknown - os=-go32 - ;; - i386-mingw32 | mingw32) - basic_machine=i386-unknown - os=-mingw32 - ;; - i386-qnx | qnx) - basic_machine=i386-qnx - ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -492,6 +598,10 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; miniframe) basic_machine=m68000-convergent ;; @@ -513,12 +623,20 @@ case $basic_machine in mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; monitor) basic_machine=m68k-rom68k os=-coff ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; msdos) - basic_machine=i386-unknown + basic_machine=i386-pc os=-msdos ;; mvs) @@ -582,9 +700,16 @@ case $basic_machine in basic_machine=i960-intel os=-mon960 ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; np1) basic_machine=np1-gould ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf @@ -614,28 +739,28 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5 | k5 | k6 | nexen) + pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; - pentiumpro | p6 | 6x86) + pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) - basic_machine=i786-pc + basic_machine=i686-pc ;; - pentium-* | p5-* | k5-* | k6-* | nexen-*) + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-* | 6x86-*) + pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; - power) basic_machine=rs6000-ibm + power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; @@ -647,9 +772,23 @@ case $basic_machine in ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; ps2) basic_machine=i386-ibm ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -660,6 +799,12 @@ case $basic_machine in rtpc | rtpc-*) basic_machine=romp-ibm ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; sa29200) basic_machine=a29k-amd os=-udi @@ -671,7 +816,7 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; - sparclite-wrs) + sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -729,6 +874,10 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; symmetry) basic_machine=i386-sequent os=-dynix @@ -737,12 +886,20 @@ case $basic_machine in basic_machine=t3e-cray os=-unicos ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; tower | tower-32) basic_machine=m68k-ncr ;; @@ -789,6 +946,10 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; xmp) basic_machine=xmp-cray os=-unicos @@ -832,13 +993,20 @@ case $basic_machine in vax) basic_machine=vax-dec ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; - sparc | sparcv9) + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) @@ -860,6 +1028,9 @@ case $basic_machine in basic_machine=c4x-none os=-coff ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 @@ -916,14 +1087,30 @@ case $os in | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -opened* | -openstep* | -oskit*) + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* | -morphos*) # Remember, each alternative MUST END IN *, to match a version number. ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mon960* | -lnews*) + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` @@ -940,6 +1127,9 @@ case $os in -opened*) os=-openedition ;; + -wince*) + os=-wince + ;; -osfrose*) os=-osfrose ;; @@ -955,6 +1145,9 @@ case $os in -acis*) os=-aos ;; + -atheos*) + os=-atheos + ;; -386bsd) os=-bsd ;; @@ -964,6 +1157,9 @@ case $os in -ns2 ) os=-nextstep2 ;; + -nsk*) + os=-nsk + ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -977,9 +1173,6 @@ case $os in -oss*) os=-sysv3 ;; - -qnx) - os=-qnx4 - ;; -svr4) os=-sysv4 ;; @@ -1001,7 +1194,7 @@ case $os in -xenix) os=-xenix ;; - -*mint | -*MiNT) + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -none) @@ -1035,6 +1228,10 @@ case $basic_machine in arm*-semi) os=-aout ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; pdp11-*) os=-none ;; @@ -1143,7 +1340,7 @@ case $basic_machine in *-masscomp) os=-rtu ;; - f301-fujitsu) + f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) @@ -1221,12 +1418,23 @@ case $basic_machine in -mpw* | -macos*) vendor=apple ;; - -*mint | -*MiNT) + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; + -vos*) + vendor=stratus + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/boehm-gc/configure b/boehm-gc/configure index 6e2a89cb137..6805af9e03a 100755 --- a/boehm-gc/configure +++ b/boehm-gc/configure @@ -2693,8 +2693,7 @@ EOF THREADLIBS="-lpthread -lrt" ;; *-*-freebsd*) - echo "configure: warning: "Threaded GC is prone to deadlock before FreeBSD 4.5."" 1>&2 - echo "configure: warning: "Related symptom is pthread_join returns spurious EINTR."" 1>&2 + echo "configure: warning: "FreeBSD does not yet fully support threads with Boehm GC."" 1>&2 cat >> confdefs.h <<\EOF #define GC_FREEBSD_THREADS 1 EOF @@ -2739,7 +2738,7 @@ esac echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:2743: checking for dlopen in -ldl" >&5 +echo "configure:2742: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2747,7 +2746,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <<EOF -#line 2751 "configure" +#line 2750 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -2758,7 +2757,7 @@ int main() { dlopen() ; return 0; } EOF -if { (eval echo configure:2762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2761: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2814,8 +2813,16 @@ esac machdep= case "$host" in - alpha*-*-*) - machdep="alpha_mach_dep.lo" +# alpha_mach_dep.s assumes that pointers are not saved in fp registers. +# Gcc on a 21264 can spill pointers to fp registers. Oops. +# alpha*-*-*) +# machdep="alpha_mach_dep.lo" +# ;; + i?86-*-solaris2.[89]*) + cat >> confdefs.h <<\EOF +#define SOLARIS25_PROC_VDB_BUG_FIXED 1 +EOF + ;; alpha-*-openbsd*) if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then @@ -2845,12 +2852,6 @@ fi fi ;; - i?86-*-solaris2.[89]*) - cat >> confdefs.h <<\EOF -#define SOLARIS25_PROC_VDB_BUG_FIXED 1 -EOF - - ;; mipstx39-*-elf*) machdep="mips_ultrix_mach_dep.lo" cat >> confdefs.h <<\EOF @@ -2873,12 +2874,16 @@ EOF ;; sparc-sun-solaris2.3*) + machdep="sparc_mach_dep.lo" cat >> confdefs.h <<\EOF #define SUNOS53_SHARED_LIB 1 EOF ;; - ia64-*-hpux*) + sparc-sun-solaris2.*) + machdep="sparc_mach_dep.lo" + ;; + ia64-*-*) machdep="mach_dep.lo ia64_save_regs_in_stack.lo" ;; esac @@ -2964,7 +2969,17 @@ EOF EOF case $host in + ia64-*-linux* ) + cat >> confdefs.h <<\EOF +#define MAKE_BACK_GRAPH 1 +EOF + + ;; x86-*-linux* | i586-*-linux* | i686-*-linux* ) + cat >> confdefs.h <<\EOF +#define MAKE_BACK_GRAPH 1 +EOF + echo "configure: warning: "Client must not use -fomit-frame-pointer."" 1>&2 cat >> confdefs.h <<\EOF #define SAVE_CALL_COUNT 8 diff --git a/boehm-gc/configure.in b/boehm-gc/configure.in index 661d0189725..d22516c2f00 100644 --- a/boehm-gc/configure.in +++ b/boehm-gc/configure.in @@ -90,8 +90,7 @@ case "$THREADS" in THREADLIBS="-lpthread -lrt" ;; *-*-freebsd*) - AC_MSG_WARN("Threaded GC is prone to deadlock before FreeBSD 4.5.") - AC_MSG_WARN("Related symptom is pthread_join returns spurious EINTR.") + AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.") AC_DEFINE(GC_FREEBSD_THREADS) INCLUDES="$INCLUDES -pthread" THREADLIBS=-pthread @@ -155,8 +154,13 @@ AC_SUBST(CXXINCLUDES) machdep= case "$host" in - alpha*-*-*) - machdep="alpha_mach_dep.lo" +# alpha_mach_dep.s assumes that pointers are not saved in fp registers. +# Gcc on a 21264 can spill pointers to fp registers. Oops. +# alpha*-*-*) +# machdep="alpha_mach_dep.lo" +# ;; + i?86-*-solaris2.[[89]]*) + AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED) ;; alpha-*-openbsd*) if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then @@ -164,9 +168,6 @@ case "$host" in AM_DISABLE_SHARED fi ;; - i?86-*-solaris2.[[89]]*) - AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED) - ;; mipstx39-*-elf*) machdep="mips_ultrix_mach_dep.lo" AC_DEFINE(STACKBASE, __stackbase) @@ -180,9 +181,13 @@ case "$host" in AC_DEFINE(NO_EXECUTE_PERMISSION) ;; sparc-sun-solaris2.3*) + machdep="sparc_mach_dep.lo" AC_DEFINE(SUNOS53_SHARED_LIB) ;; - ia64-*-hpux*) + sparc-sun-solaris2.*) + machdep="sparc_mach_dep.lo" + ;; + ia64-*-*) machdep="mach_dep.lo ia64_save_regs_in_stack.lo" ;; esac @@ -243,7 +248,11 @@ AC_ARG_ENABLE(full-debug, AC_DEFINE(KEEP_BACK_PTRS) AC_DEFINE(DBG_HDRS_ALL) case $host in + ia64-*-linux* ) + AC_DEFINE(MAKE_BACK_GRAPH) + ;; x86-*-linux* | i586-*-linux* | i686-*-linux* ) + AC_DEFINE(MAKE_BACK_GRAPH) AC_MSG_WARN("Client must not use -fomit-frame-pointer.") AC_DEFINE(SAVE_CALL_COUNT, 8) ;; diff --git a/boehm-gc/dbg_mlc.c b/boehm-gc/dbg_mlc.c index b1bb941ccf8..e875c880f07 100644 --- a/boehm-gc/dbg_mlc.c +++ b/boehm-gc/dbg_mlc.c @@ -246,6 +246,9 @@ word integer; # ifdef KEEP_BACK_PTRS ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); # endif +# ifdef MAKE_BACK_GRAPH + ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0); +# endif ((oh *)p) -> oh_string = string; ((oh *)p) -> oh_int = integer; # ifndef SHORT_DBG_HDRS @@ -275,6 +278,9 @@ word integer; # ifdef KEEP_BACK_PTRS ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); # endif +# ifdef MAKE_BACK_GRAPH + ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0); +# endif ((oh *)p) -> oh_string = string; ((oh *)p) -> oh_int = integer; # ifndef SHORT_DBG_HDRS diff --git a/boehm-gc/doc/README b/boehm-gc/doc/README index b161ccf4a46..6ac37c6c8ce 100644 --- a/boehm-gc/doc/README +++ b/boehm-gc/doc/README @@ -27,7 +27,7 @@ are GPL'ed, but with an exception that should cover all uses in the collector. (If you are concerned about such things, I recommend you look at the notice in config.guess or ltmain.sh.) -This is version 6.1alpha1 of a conservative garbage collector for C and C++. +This is version 6.1alpha3 of a conservative garbage collector for C and C++. You might find a more recent version of this at diff --git a/boehm-gc/doc/README.changes b/boehm-gc/doc/README.changes index 8c00e938b5f..232938b4375 100644 --- a/boehm-gc/doc/README.changes +++ b/boehm-gc/doc/README.changes @@ -1413,6 +1413,61 @@ Since 6.0: less common thread implementations, since some of the original code didn't stand up to close scrutiny. Support for the next pthreads implementation should be easier to add. + +Since 6.1alpha1: + - No longer wrap read by default in multithreaded applications. It was + pointed out on the libgcj list that this holds the allocation lock for + way too long if the read blocks. For now, reads into the heap are + broken with incremental collection. It's possible to turn this back on + if you make sure that read calls don't block (e.g. by calling select + first). + - Fix ifdef in Solaris_threads.h to refer to GC_SOLARIS_THREADS. + - Added check for environment variable GC_IGNORE_GCJ_INFO. + - Added printing of stop-the-world GC times if GC_PRINT_STATS environment + variable is set. + - The calloc definition in leak_detector.h was missing parentheses, and + realloc was missing a second argument to GC_REALLOC. + (Thanks to Elrond (elrond<at>samba-tng.org).) + - Added GC_PRINT_BACK_HEIGHT environment variable and associated + code, mostly in the new file backgraph.c. See doc/README.environment. + - Added -DUSE_GLOBAL_ALLOC to work around a Windows NT issue. (Thanks to + Jonathan Clark.) + - Integrated port to NEC EWS4800 (MIPS-based workstation, with somewhat + different address-space layout). This may help for other machines with + holes in the data segment. (Thanks to Hironori Sakamoto.) + - Changed the order in which GC_push_roots and friends push things onto + the mark stack. GC_push_all calls need to come first, since we can't + necessarily recovere if those overflow the mark stack. (Thanks to + Matthew Flatt for tracking down the problem.) + - Some minor cleanups to mostly support the Intel compiler on Linux/IA64. + +Since 6.1 alpha2: + - Minor cleanup on the gcconfig.h section for SPARC. + - Minor fix to support Intel compiler for I386/Linux. (Thanks to Sven + Hartrumpf.) + - Added SPARC V9 (64-bit) support. (Thanks to Jeff Sturm.) + - Restructured the way in which we determine whether or not to keep + call stacks for debug allocation. By default SAVE_CALL_COUNT is + now zero on all platforms. Added SAVE_CALL_NARGS parameters. + If possible, use execinfo.h to capture call stack. (This should + add support for a number of new platforms, though often at + considerable runtime expense.) + - Try to print symbolic information for call stacks. On Linux, we + do this with a combination of execinfo.h and running addr2line in + a separate process. This is both much more expensive and much more + useful. Amazingly, it seems to be fast enough for most purposes. + - Redefined strdup if -DREDIRECT_MALLOC is given. + - Changed incremental collector and MPROTECT_VDB implementation so that, + under favorable conditions, pointerfree objects are not protected. + Added GC_incremental_protection_needs() to determine ahead of time whether + pointerfree objects may be protected. Replaced GC_write_hint() with + GC_remove_protection(). + - Added test for GC_ENABLE_INCREMENTAL environment variable. + - Made GC_time_limit runtime configurable. Added GC_PAUSE_TIME_TARGET + environment variable. + - Eliminated GC_page_sz, a duplicate of GC_page_size. + - Caused the Solaris and Irix thread creation primitives to call + GC_init_inner(). To do: diff --git a/boehm-gc/doc/README.environment b/boehm-gc/doc/README.environment index 5760342a86a..6b25af1f6fe 100644 --- a/boehm-gc/doc/README.environment +++ b/boehm-gc/doc/README.environment @@ -1,5 +1,5 @@ The garbage collector looks at a number of environment variables which are -the used to affect its operation. These are examined only on Un*x-like +then used to affect its operation. These are examined only on Un*x-like platforms. GC_INITIAL_HEAP_SIZE=<bytes> - Initial heap size in bytes. May speed up @@ -32,6 +32,47 @@ GC_NPROCS=<n> - Linux w/threads only. Explicitly sets the number of processors GC_NO_BLACKLIST_WARNING - Prevents the collector from issuing "Needed to allocate blacklisted block at ..." warnings. +GC_IGNORE_GCJ_INFO - Ignore the type descriptors implicitly supplied by + GC_gcj_malloc and friends. This is useful for debugging + descriptor generation problems, and possibly for + temporarily working around such problems. It forces a + fully conservative scan of all heap objects except + those known to be pointerfree, and may thus have other + adverse effects. + +GC_PRINT_BACK_HEIGHT - Print max length of chain through unreachable objects + ending in a reachable one. If this number remains + bounded, then the program is "GC robust". This ensures + that a fixed number of misidentified pointers can only + result in a bounded space leak. This currently only + works if debugging allocation is used throughout. + It increases GC space and time requirements appreciably. + This feature is still somewhat experimental, and requires + that the collector have been built with MAKE_BACK_GRAPH + defined. For details, see Boehm, "Bounding Space Usage + of Conservative Garbage Collectors", POPL 2001, or + http://lib.hpl.hp.com/techpubs/2001/HPL-2001-251.html . + +GC_ENABLE_INCREMENTAL - Turn on incremental collection at startup. Note that, + depending on platform and collector configuration, this + may involve write protecting pieces of the heap to + track modifications. These pieces may include pointerfree + objects or not. Although this is intended to be + transparent, it may cause unintended system call failures. + Use with caution. + +GC_PAUSE_TIME_TARGET - Set the desired garbage collector pause time in msecs. + This only has an effect if incremental collection is enabled. + If a collection requires appreciably more time than this, + the client will be restarted, and the collector will need + to do additional work to compensate. The special value + "999999" indicates that pause time is unlimited, and the + incremental collector will behave completely like a + simple generational collector. If the collector is + configured for parallel marking, and run on a multiprocessor, + incremental collection should only be used with unlimited + pause time. + The following turn on runtime flags that are also program settable. Checked only during initialization. We expect that they will usually be set through other means, but this may help with debugging and testing: diff --git a/boehm-gc/doc/README.win32 b/boehm-gc/doc/README.win32 index 417281da43d..b1a6ec59664 100644 --- a/boehm-gc/doc/README.win32 +++ b/boehm-gc/doc/README.win32 @@ -1,8 +1,8 @@ The collector has at various times been compiled under Windows 95 & NT, with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, with -the GNU win32 environment, with Borland 4.5, and recently with -Watcom C. It is likely that some of these have been broken in the -meantime. Patches are appreciated. +the GNU win32 environment, with Borland 4.5, with Watcom C, and recently +with the Digital Mars compiler. It is likely that some of these have been +broken in the meantime. Patches are appreciated. It runs under both win32s and win32, but with different semantics. Under win32, all writable pages outside of the heaps and stack are @@ -45,6 +45,13 @@ window colors.) In general -DREDIRECT_MALLOC is unlikely to work unless the application is completely statically linked. +The collector normally allocates memory from the OS with VirtualAlloc. +This appears to cause problems under Windows NT and Windows 2000 (but +not Windows 95/98) if the memory is later passed to CreateDIBitmap. +To work around this problem, build the collector with -DUSE_GLOBAL_ALLOC. +This is currently incompatible with -DUSE_MUNMAP. (Thanks to Jonathan +Clark for tracking this down.) + For Microsoft development tools, rename NT_MAKEFILE as MAKEFILE. (Make sure that the CPU environment variable is defined to be i386.) In order to use the gc_cpp.h C++ interface, all diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c index 984253aa873..d80600bb1d7 100644 --- a/boehm-gc/dyn_load.c +++ b/boehm-gc/dyn_load.c @@ -79,6 +79,14 @@ # define l_name lm_name #endif +#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ + (defined(FREEBSD) && defined(__ELF__)) || \ + (defined(NETBSD) && defined(__ELF__)) || defined(HURD) +# include <stddef.h> +# include <elf.h> +# include <link.h> +#endif + /* Newer versions of GNU/Linux define this macro. We * define it similarly for any ELF systems that don't. */ # ifndef ElfW @@ -438,10 +446,6 @@ static char *parse_map_entry(char *buf_ptr, word *start, word *end, /* For glibc 2.2.4+. Unfortunately, it doesn't work for older */ /* versions. Thanks to Jakub Jelinek for most of the code. */ -#include <stddef.h> -#include <elf.h> -#include <link.h> - # if defined(LINUX) /* Are others OK here, too? */ \ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) diff --git a/boehm-gc/finalize.c b/boehm-gc/finalize.c index d69ba6f1e22..a316010a680 100644 --- a/boehm-gc/finalize.c +++ b/boehm-gc/finalize.c @@ -838,3 +838,4 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void)) # endif return(result); } + diff --git a/boehm-gc/gcj_mlc.c b/boehm-gc/gcj_mlc.c index 7e79521eb1f..89f0d728a57 100644 --- a/boehm-gc/gcj_mlc.c +++ b/boehm-gc/gcj_mlc.c @@ -54,6 +54,7 @@ ptr_t * GC_gcjdebugobjfreelist; void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) { register int i; + GC_bool ignore_gcj_info; DCL_LOCK_STATE; GC_init(); /* In case it's not already done. */ @@ -65,6 +66,12 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) return; } GC_gcj_malloc_initialized = TRUE; + ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO")); +# ifdef CONDPRINT + if (GC_print_stats && ignore_gcj_info) { + GC_printf0("Gcj-style type information is disabled!\n"); + } +# endif GC_mark_procs[mp_index] = (GC_mark_proc)mp; if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index"); /* Set up object kind gcj-style indirect descriptor. */ @@ -75,9 +82,17 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) GC_gcj_kind = GC_n_kinds++; GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist; GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0; - GC_obj_kinds[GC_gcj_kind].ok_descriptor = - (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) | GC_DS_PER_OBJECT); - GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE; + if (ignore_gcj_info) { + /* Use a simple length-based descriptor, thus forcing a fully */ + /* conservative scan. */ + GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH); + GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE; + } else { + GC_obj_kinds[GC_gcj_kind].ok_descriptor = + (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) + | GC_DS_PER_OBJECT); + GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE; + } GC_obj_kinds[GC_gcj_kind].ok_init = TRUE; /* Set up object kind for objects that require mark proc call. */ GC_gcjdebugobjfreelist = (ptr_t *) @@ -88,9 +103,14 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) GC_gcj_debug_kind = GC_n_kinds++; GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist; GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0; - GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor = - GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */); - GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE; + if (ignore_gcj_info) { + GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH); + GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE; + } else { + GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor = + GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */); + GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE; + } GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE; UNLOCK(); ENABLE_SIGNALS(); diff --git a/boehm-gc/include/Makefile.in b/boehm-gc/include/Makefile.in index 3c8f7fb63e7..611f5651839 100644 --- a/boehm-gc/include/Makefile.in +++ b/boehm-gc/include/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated automatically by automake 1.4-p1 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation @@ -96,7 +96,8 @@ target_all = @target_all@ AUTOMAKE_OPTIONS = foreign -include_HEADERS = gc.h gc_backptr.h gc_local_alloc.h gc_pthread_redirects.h gc_cpp.h +include_HEADERS = gc.h gc_backptr.h gc_local_alloc.h \ + gc_pthread_redirects.h gc_cpp.h CONFIG_CLEAN_FILES = HEADERS = $(include_HEADERS) diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index 9e5447b0458..69075b0669e 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -305,6 +305,20 @@ GC_API int GC_dont_precollect; /* Don't collect as part of */ */ GC_API void GC_init GC_PROTO((void)); +GC_API unsigned long GC_time_limit; + /* If incremental collection is enabled, */ + /* We try to terminate collections */ + /* after this many milliseconds. Not a */ + /* hard time bound. Setting this to */ + /* GC_TIME_UNLIMITED will essentially */ + /* disable incremental collection while */ + /* leaving generational collection */ + /* enabled. */ +# define GC_TIME_UNLIMITED 999999 + /* Setting GC_time_limit to this value */ + /* will disable the "pause time exceeded */ + /* tests. */ + /* * general purpose allocation routines, with roughly malloc calling conv. * The atomic versions promise that no relevant pointers are contained @@ -463,6 +477,16 @@ GC_API size_t GC_get_total_bytes GC_PROTO((void)); /* functional if GC_parallel is TRUE. */ GC_API void GC_enable_incremental GC_PROTO((void)); +/* Does incremental mode write-protect pages? Returns zero or */ +/* more of the following, or'ed together: */ +#define GC_PROTECTS_POINTER_HEAP 1 /* May protect non-atomic objs. */ +#define GC_PROTECTS_PTRFREE_HEAP 2 +#define GC_PROTECTS_STATIC_DATA 4 /* Curently never. */ +#define GC_PROTECTS_STACK 8 /* Probably impractical. */ + +#define GC_PROTECTS_NONE 0 +GC_API int GC_incremental_protection_needs GC_PROTO((void)); + /* Perform some garbage collection work, if appropriate. */ /* Return 0 if there is no more work to be done. */ /* Typically performs an amount of work corresponding roughly */ diff --git a/boehm-gc/include/leak_detector.h b/boehm-gc/include/leak_detector.h index 6786825ab6d..0674ab4d09f 100644 --- a/boehm-gc/include/leak_detector.h +++ b/boehm-gc/include/leak_detector.h @@ -1,7 +1,7 @@ #define GC_DEBUG #include "gc.h" #define malloc(n) GC_MALLOC(n) -#define calloc(m,n) GC_MALLOC(m*n) +#define calloc(m,n) GC_MALLOC((m)*(n)) #define free(p) GC_FREE(p) -#define realloc(p,n) GC_REALLOC(n) +#define realloc(p,n) GC_REALLOC((p),(n)) #define CHECK_LEAKS() GC_gcollect() diff --git a/boehm-gc/include/private/dbg_mlc.h b/boehm-gc/include/private/dbg_mlc.h index 6f5b3c8677d..5378835811c 100644 --- a/boehm-gc/include/private/dbg_mlc.h +++ b/boehm-gc/include/private/dbg_mlc.h @@ -46,7 +46,8 @@ /* Stored both one past the end of user object, and one before */ /* the end of the object as seen by the allocator. */ -# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) +# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) \ + || defined(MAKE_BACK_GRAPH) /* Pointer "source"s that aren't real locations. */ /* Used in oh_back_ptr fields and as "source" */ /* argument to some marking functions. */ @@ -60,28 +61,42 @@ /* Object header */ typedef struct { -# ifdef KEEP_BACK_PTRS - GC_hidden_pointer oh_back_ptr; - /* We make sure that we only store even valued */ - /* pointers here, so that the hidden version has */ - /* the least significant bit set. We never */ - /* overwrite a value with the least significant */ - /* bit clear, thus ensuring that we never overwrite */ - /* a free list link field. */ - /* Note that blocks dropped by black-listing will */ - /* also have the lsb clear once debugging has */ - /* started. */ - /* The following are special back pointer values. */ - /* Note that the "hidden" (i.e. bitwise */ - /* complemented version) of these is actually */ - /* stored. */ +# if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) + /* We potentially keep two different kinds of back */ + /* pointers. KEEP_BACK_PTRS stores a single back */ + /* pointer in each reachable object to allow reporting */ + /* of why an object was retained. MAKE_BACK_GRAPH */ + /* builds a graph containing the inverse of all */ + /* "points-to" edges including those involving */ + /* objects that have just become unreachable. This */ + /* allows detection of growing chains of unreachable */ + /* objects. It may be possible to eventually combine */ + /* both, but for now we keep them separate. Both */ + /* kinds of back pointers are hidden using the */ + /* following macros. In both cases, the plain version */ + /* is constrained to have an least significant bit of 1,*/ + /* to allow it to be distinguished from a free list */ + /* link. This means the plain version must have an */ + /* lsb of 0. */ + /* Note that blocks dropped by black-listing will */ + /* also have the lsb clear once debugging has */ + /* started. */ + /* We're careful never to overwrite a value with lsb 0. */ # if ALIGNMENT == 1 /* Fudge back pointer to be even. */ # define HIDE_BACK_PTR(p) HIDE_POINTER(~1 & (GC_word)(p)) # else # define HIDE_BACK_PTR(p) HIDE_POINTER(p) # endif -# ifdef ALIGN_DOUBLE + +# ifdef KEEP_BACK_PTRS + GC_hidden_pointer oh_back_ptr; +# endif +# ifdef MAKE_BACK_GRAPH + GC_hidden_pointer oh_bg_ptr; +# endif +# if defined(ALIGN_DOUBLE) && \ + (defined(KEEP_BACK_PTRS) != defined(MAKE_BACK_GRAPH)) word oh_dummy; # endif # endif @@ -139,9 +154,9 @@ typedef struct { GC_bool GC_has_other_debug_info(/* p */); #endif -#ifdef KEEP_BACK_PTRS +#if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) # define GC_HAS_DEBUG_INFO(p) \ - ((((oh *)p)->oh_back_ptr & 1) && GC_has_other_debug_info(p)) + ((*((word *)p) & 1) && GC_has_other_debug_info(p)) #else # define GC_HAS_DEBUG_INFO(p) GC_has_other_debug_info(p) #endif diff --git a/boehm-gc/include/private/gc_pmark.h b/boehm-gc/include/private/gc_pmark.h index 43077e9f616..872065702f0 100644 --- a/boehm-gc/include/private/gc_pmark.h +++ b/boehm-gc/include/private/gc_pmark.h @@ -136,7 +136,8 @@ extern mse * GC_mark_stack; /* Set *new_hdr_p to corr. hdr. */ #ifdef __STDC__ # ifdef PRINT_BLACK_LIST - ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, word source); + ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, + ptr_t source); # else ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p); # endif diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h index 92067d24e70..ae406cb9010 100644 --- a/boehm-gc/include/private/gc_priv.h +++ b/boehm-gc/include/private/gc_priv.h @@ -249,20 +249,6 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ #ifdef SAVE_CALL_CHAIN -/* - * Number of frames and arguments to save in objects allocated by - * debugging allocator. - */ -# ifndef SAVE_CALL_COUNT -# define NFRAMES 6 /* Number of frames to save. Even for */ - /* alignment reasons. */ -# else -# define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1) -# endif -# define NARGS 2 /* Mumber of arguments to save for each call. */ - -# define NEED_CALLINFO - /* Fill in the pc and argument information for up to NFRAMES of my */ /* callers. Ignore my frame and my callers frame. */ struct callinfo; @@ -270,14 +256,6 @@ void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES])); void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES])); -#else - -# ifdef GC_ADD_CALLER -# define NFRAMES 1 -# define NARGS 0 -# define NEED_CALLINFO -# endif - #endif #ifdef NEED_CALLINFO @@ -396,7 +374,8 @@ struct hblk; /* See below. */ + GC_page_size-1) # else # if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \ - (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) + (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \ + (defined(SUNOS5) && !defined(USE_MMAP)) # define GET_MEM(bytes) HBLKPTR((size_t) \ calloc(1, (size_t)bytes + GC_page_size) \ + GC_page_size-1) @@ -787,12 +766,11 @@ struct hblkhdr { # define BODY_SZ (HBLKSIZE/sizeof(word)) struct hblk { -# if 0 /* DISCARDWORDS no longer supported */ - word garbage[DISCARD_WORDS]; -# endif word hb_body[BODY_SZ]; }; +# define HBLK_IS_FREE(hdr) ((hdr) -> hb_map == GC_invalid_map) + # define OBJ_SZ_TO_BLOCKS(sz) \ divHBLKSZ(WORDS_TO_BYTES(sz) + HBLKSIZE-1) /* Size of block (in units of HBLKSIZE) needed to hold objects of */ @@ -1765,8 +1743,12 @@ GC_bool GC_page_was_ever_dirty GC_PROTO((struct hblk *h)); void GC_is_fresh GC_PROTO((struct hblk *h, word n)); /* Assert the region currently contains no */ /* valid pointers. */ -void GC_write_hint GC_PROTO((struct hblk *h)); - /* h is about to be written. */ +void GC_remove_protection GC_PROTO((struct hblk *h, word nblocks, + GC_bool pointerfree)); + /* h is about to be writteni or allocated. Ensure */ + /* that it's not write protected by the virtual */ + /* dirty bit implementation. */ + void GC_dirty_init GC_PROTO((void)); /* Slow/general mark bit manipulation: */ diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h index 647bd5af3f7..e06cc4abc56 100644 --- a/boehm-gc/include/private/gcconfig.h +++ b/boehm-gc/include/private/gcconfig.h @@ -85,9 +85,12 @@ # endif # define mach_type_known # endif -# if defined(mips) || defined(__mips) +# if defined(mips) || defined(__mips) || defined(_mips) # define MIPS -# if !defined(LINUX) +# if defined(nec_ews) || defined(_nec_ews) +# define EWS4800 +# endif +# if !defined(LINUX) && !defined(EWS4800) # if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__) # define ULTRIX # else @@ -726,6 +729,7 @@ # define ELF_CLASS ELFCLASS64 # else # define ALIGNMENT 4 /* Required by hardware */ +# define CPP_WORDSZ 32 # endif # define ALIGN_DOUBLE # ifdef SUNOS5 @@ -735,8 +739,12 @@ extern char * GC_SysVGetDataStart(); # define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext) # define DATAEND (&_end) -# ifndef USE_MMAP +# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) # define USE_MMAP + /* Otherwise we now use calloc. Mmap may result in the */ + /* heap interleaved with thread stacks, which can result in */ + /* excessive blacklisting. Sbrk is unusable since it */ + /* doesn't interact correctly with the system malloc. */ # endif # ifdef USE_MMAP # define HEAP_START (ptr_t)0x40000000 @@ -760,7 +768,9 @@ # define GETPAGESIZE() sysconf(_SC_PAGESIZE) /* getpagesize() appeared to be missing from at least one */ /* Solaris 5.4 installation. Weird. */ -# define DYNAMIC_LOADING +# if CPP_WORDSZ == 32 +# define DYNAMIC_LOADING +# endif # endif # ifdef SUNOS4 # define OS_TYPE "SUNOS4" @@ -782,7 +792,6 @@ # define DYNAMIC_LOADING # endif # ifdef DRSNX -# define CPP_WORDSZ 32 # define OS_TYPE "DRSNX" extern char * GC_SysVGetDataStart(); extern int etext; @@ -805,7 +814,6 @@ # ifdef __arch64__ # define STACKBOTTOM ((ptr_t) 0x80000000000ULL) # define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, &_etext) -# define CPP_WORDSZ 64 # else # define STACKBOTTOM ((ptr_t) 0xf0000000) # define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext) @@ -858,7 +866,7 @@ # endif # ifdef SUNOS5 # define OS_TYPE "SUNOS5" - extern int _etext, _end; + extern int _etext, _end; extern char * GC_SysVGetDataStart(); # define DATASTART GC_SysVGetDataStart(0x1000, &_etext) # define DATAEND (&_end) @@ -867,15 +875,20 @@ /* base is a property of the executable, so this should not break */ /* old executables. */ /* HEURISTIC2 probably works, but this appears to be preferable. */ -# include <sys/vmparam.h> +# include <sys/vm.h> # define STACKBOTTOM USRSTACK -/** At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ +/* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ +/* It appears to be fixed in 2.8 and 2.9. */ # ifdef SOLARIS25_PROC_VDB_BUG_FIXED # define PROC_VDB # endif # define DYNAMIC_LOADING -# ifndef USE_MMAP +# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) # define USE_MMAP + /* Otherwise we now use calloc. Mmap may result in the */ + /* heap interleaved with thread stacks, which can result in */ + /* excessive blacklisting. Sbrk is unusable since it */ + /* doesn't interact correctly with the system malloc. */ # endif # ifdef USE_MMAP # define HEAP_START (ptr_t)0x40000000 @@ -900,6 +913,10 @@ # define ELF_CLASS ELFCLASS32 # endif # ifdef LINUX +# ifndef __GNUC__ + /* The Intel compiler doesn't like inline assembly */ +# define USE_GENERIC_PUSH_REGS +# endif # define OS_TYPE "LINUX" # define LINUX_STACKBOTTOM # if 0 @@ -1035,6 +1052,8 @@ # ifdef __ELF__ # define DYNAMIC_LOADING # endif + extern char etext; +# define DATASTART ((ptr_t)(&etext)) # endif # ifdef NETBSD # define OS_TYPE "NETBSD" @@ -1045,7 +1064,7 @@ # ifdef BSDI # define OS_TYPE "BSDI" # endif -# if defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \ +# if defined(OPENBSD) || defined(NETBSD) \ || defined(THREE86BSD) || defined(BSDI) # define HEURISTIC2 extern char etext; @@ -1113,6 +1132,29 @@ /* instead. But some kernel versions seem to give the wrong */ /* value from /proc. */ # endif /* Linux */ +# ifdef EWS4800 +# define HEURISTIC2 +# if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64) + extern int _fdata[], _end[]; +# define DATASTART ((ptr_t)_fdata) +# define DATAEND ((ptr_t)_end) +# define CPP_WORDSZ _MIPS_SZPTR +# define ALIGNMENT (_MIPS_SZPTR/8) +# else + extern int etext, edata, end; + extern int _DYNAMIC_LINKING, _gp; +# define DATASTART ((ptr_t)((((word)&etext + 0x3ffff) & ~0x3ffff) \ + + ((word)&etext & 0xffff))) +# define DATAEND (&edata) +# define DATASTART2 (&_DYNAMIC_LINKING \ + ? (ptr_t)(((word)&_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \ + : (ptr_t)&edata) +# define DATAEND2 (&end) +# define ALIGNMENT 4 +# endif +# define OS_TYPE "EWS4800" +# define USE_GENERIC_PUSH_REGS 1 +# endif # ifdef ULTRIX # define HEURISTIC2 # define DATASTART (ptr_t)0x10000000 @@ -1394,7 +1436,13 @@ # define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom) # define SEARCH_FOR_DATA_START # define DATASTART GC_data_start -# define DYNAMIC_LOADING +# ifdef __GNUC__ +# define DYNAMIC_LOADING +# else + /* In the Intel compiler environment, we seem to end up with */ + /* statically linked executables and an undefined reference */ + /* to _DYNAMIC */ +# endif # define MPROTECT_VDB /* Requires Linux 2.3.47 or later. */ extern int _end; @@ -1707,17 +1755,68 @@ /* descriptions. */ # define USE_GENERIC_PUSH_REGS # endif -# if defined(I386) && defined(LINUX) + +# if defined(SPARC) +# define ASM_CLEAR_CODE /* Stack clearing is crucial, and we */ + /* include assembly code to do it well. */ +# endif + +/* Can we save call chain in objects for debugging? */ +/* SET NFRAMES (# of saved frames) and NARGS (#of args for each frame) */ +/* to reasonable values for the platform. */ +/* Set SAVE_CALL_CHAIN if we can. SAVE_CALL_COUNT can be specified at */ +/* build time, though we feel free to adjust it slightly. */ +/* Define NEED_CALLINFO if we either save the call stack or */ +/* GC_ADD_CALLER is defined. */ +#ifdef LINUX +# include <features.h> +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2 +# define HAVE_BUILTIN_BACKTRACE +# endif +#endif + +#if defined(SPARC) +# define CAN_SAVE_CALL_STACKS +# define CAN_SAVE_CALL_ARGS +#endif +#if defined(I386) && defined(LINUX) /* SAVE_CALL_CHAIN is supported if the code is compiled to save */ /* frame pointers by default, i.e. no -fomit-frame-pointer flag. */ -# ifdef SAVE_CALL_COUNT +# define CAN_SAVE_CALL_STACKS +# define CAN_SAVE_CALL_ARGS +#endif +#if defined(HAVE_BUILTIN_BACKTRACE) && !defined(CAN_SAVE_CALL_STACKS) +# define CAN_SAVE_CALL_STACKS +#endif + +# if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \ + && defined(CAN_SAVE_CALL_STACKS) # define SAVE_CALL_CHAIN # endif +# ifdef SAVE_CALL_CHAIN +# if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS) +# define NARGS SAVE_CALL_NARGS +# else +# define NARGS 0 /* Number of arguments to save for each call. */ +# endif # endif -# if defined(SPARC) -# define SAVE_CALL_CHAIN -# define ASM_CLEAR_CODE /* Stack clearing is crucial, and we */ - /* include assembly code to do it well. */ +# ifdef SAVE_CALL_CHAIN +# ifndef SAVE_CALL_COUNT +# define NFRAMES 6 /* Number of frames to save. Even for */ + /* alignment reasons. */ +# else +# define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1) +# endif +# define NEED_CALLINFO +# endif /* SAVE_CALL_CHAIN */ +# ifdef GC_ADD_CALLER +# define NFRAMES 1 +# define NARGS 0 +# define NEED_CALLINFO +# endif + +# if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL) +# define DBG_HDRS_ALL # endif # endif /* GCCONFIG_H */ diff --git a/boehm-gc/irix_threads.c b/boehm-gc/irix_threads.c index c894a31006d..12204fdabc2 100644 --- a/boehm-gc/irix_threads.c +++ b/boehm-gc/irix_threads.c @@ -141,8 +141,6 @@ GC_bool GC_thr_initialized = FALSE; size_t GC_min_stack_sz; -size_t GC_page_sz; - # define N_FREE_LISTS 25 ptr_t GC_stack_free_lists[N_FREE_LISTS] = { 0 }; /* GC_stack_free_lists[i] is free list for stacks of */ @@ -171,14 +169,14 @@ ptr_t GC_stack_alloc(size_t * stack_size) if (result != 0) { GC_stack_free_lists[index] = *(ptr_t *)result; } else { - result = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_sz); - result = (ptr_t)(((word)result + GC_page_sz) & ~(GC_page_sz - 1)); + result = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_size); + result = (ptr_t)(((word)result + GC_page_size) & ~(GC_page_size - 1)); /* Protect hottest page to detect overflow. */ # ifdef STACK_GROWS_UP - /* mprotect(result + search_sz, GC_page_sz, PROT_NONE); */ + /* mprotect(result + search_sz, GC_page_size, PROT_NONE); */ # else - /* mprotect(result, GC_page_sz, PROT_NONE); */ - result += GC_page_sz; + /* mprotect(result, GC_page_size, PROT_NONE); */ + result += GC_page_size; # endif } *stack_size = search_sz; @@ -438,7 +436,6 @@ void GC_thr_init() if (GC_thr_initialized) return; GC_thr_initialized = TRUE; GC_min_stack_sz = HBLKSIZE; - GC_page_sz = sysconf(_SC_PAGESIZE); (void) sigaction(SIG_SUSPEND, 0, &act); if (act.sa_handler != SIG_DFL) ABORT("Previously installed SIG_SUSPEND handler"); @@ -602,7 +599,7 @@ GC_pthread_create(pthread_t *new_thread, si -> start_routine = start_routine; si -> arg = arg; LOCK(); - if (!GC_thr_initialized) GC_thr_init(); + if (!GC_initialized) GC_init(); if (NULL == attr) { stack = 0; (void) pthread_attr_init(&new_attr); diff --git a/boehm-gc/linux_threads.c b/boehm-gc/linux_threads.c index c4a2b89a18d..b26988cef9e 100644 --- a/boehm-gc/linux_threads.c +++ b/boehm-gc/linux_threads.c @@ -1268,6 +1268,17 @@ int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval) /* cant have been recycled by pthreads. */ UNLOCK(); result = REAL_FUNC(pthread_join)(thread, retval); +# if defined (GC_FREEBSD_THREADS) + /* On FreeBSD, the wrapped pthread_join() sometimes returns (what + appears to be) a spurious EINTR which caused the test and real code + to gratuitously fail. Having looked at system pthread library source + code, I see how this return code may be generated. In one path of + code, pthread_join() just returns the errno setting of the thread + being joined. This does not match the POSIX specification or the + local man pages thus I have taken the liberty to catch this one + spurious return value properly conditionalized on GC_FREEBSD_THREADS. */ + if (result == EINTR) result = 0; +# endif if (result == 0) { LOCK(); /* Here the pthread thread id may have been recycled. */ diff --git a/boehm-gc/mach_dep.c b/boehm-gc/mach_dep.c index 35e9264bd85..b582db034df 100644 --- a/boehm-gc/mach_dep.c +++ b/boehm-gc/mach_dep.c @@ -429,7 +429,7 @@ ptr_t cold_gc_frame; *i = 0; } # if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ - || defined(UTS4) || defined(LINUX) + || defined(UTS4) || defined(LINUX) || defined(EWS4800) (void) setjmp(regs); # else (void) _setjmp(regs); @@ -492,8 +492,10 @@ ptr_t cold_gc_frame; /* 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. */ -/* We implement this as a separate file in HP/UX. */ -# ifdef IA64 +/* We now implement this as a separate assembly file, since inline */ +/* assembly code here doesn't work with either the Intel or HP */ +/* compilers. */ +# if 0 # ifdef LINUX asm(" .text"); asm(" .psr abi64"); diff --git a/boehm-gc/malloc.c b/boehm-gc/malloc.c index 943f27d337c..5ac21421bea 100644 --- a/boehm-gc/malloc.c +++ b/boehm-gc/malloc.c @@ -337,6 +337,20 @@ DCL_LOCK_STATE; { return((GC_PTR)REDIRECT_MALLOC(n*lb)); } + +# include <string.h> +# ifdef __STDC__ + char *strdup(const char *s) +# else + char *strdup(s) + char *s; +# endif + { + size_t len = strlen + 1; + char * result = ((char *)REDIRECT_MALLOC(len+1)); + BCOPY(s, result, len+1); + return result; + } # endif /* REDIRECT_MALLOC */ /* Explicitly deallocate an object p. */ diff --git a/boehm-gc/mark.c b/boehm-gc/mark.c index 4d7504799d4..70ba135f1ab 100644 --- a/boehm-gc/mark.c +++ b/boehm-gc/mark.c @@ -838,7 +838,7 @@ long GC_markers = 2; /* Normally changed by thread-library- */ /* -specific code. */ /* Mark using the local mark stack until the global mark stack is empty */ -/* and ther are no active workers. Update GC_first_nonempty to reflect */ +/* and there are no active workers. Update GC_first_nonempty to reflect */ /* progress. */ /* Caller does not hold mark lock. */ /* Caller has already incremented GC_helper_count. We decrement it, */ @@ -918,7 +918,7 @@ void GC_mark_local(mse *local_mark_stack, int id) return; } /* else there's something on the stack again, or */ - /* another help may push something. */ + /* another helper may push something. */ GC_active_count++; GC_ASSERT(GC_active_count > 0); GC_release_mark_lock(); @@ -950,8 +950,10 @@ void GC_do_parallel_mark() GC_acquire_mark_lock(); GC_ASSERT(I_HOLD_LOCK()); - GC_ASSERT(!GC_help_wanted); - GC_ASSERT(GC_active_count == 0); + /* This could be a GC_ASSERT, but it seems safer to keep it on */ + /* all the time, especially since it's cheap. */ + if (GC_help_wanted || GC_active_count != 0 || GC_helper_count != 0) + ABORT("Tried to start parallel mark in bad state"); # ifdef PRINTSTATS GC_printf1("Starting marking for mark phase number %lu\n", (unsigned long)GC_mark_no); @@ -1374,11 +1376,11 @@ ptr_t cold_gc_frame; return; } # ifdef STACK_GROWS_DOWN - GC_push_all_eager(bottom, cold_gc_frame); GC_push_all(cold_gc_frame - sizeof(ptr_t), top); + GC_push_all_eager(bottom, cold_gc_frame); # else /* STACK_GROWS_UP */ - GC_push_all_eager(cold_gc_frame, top); GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t)); + GC_push_all_eager(cold_gc_frame, top); # endif /* STACK_GROWS_UP */ } else { GC_push_all_eager(bottom, top); diff --git a/boehm-gc/mark_rts.c b/boehm-gc/mark_rts.c index a082e2b2e06..628cba289ac 100644 --- a/boehm-gc/mark_rts.c +++ b/boehm-gc/mark_rts.c @@ -252,7 +252,7 @@ GC_bool tmp; n_root_sets++; } -static roots_were_cleared = FALSE; +static GC_bool roots_were_cleared = FALSE; void GC_clear_roots GC_PROTO((void)) { @@ -522,16 +522,6 @@ ptr_t cold_gc_frame; register int i; /* - * push registers - i.e., call GC_push_one(r) for each - * register contents r. - */ -# ifdef USE_GENERIC_PUSH_REGS - GC_generic_push_regs(cold_gc_frame); -# else - GC_push_regs(); /* usually defined in machine_dep.c */ -# endif - - /* * Next push static data. This must happen early on, since it's * not robust against mark stack overflow. */ @@ -564,19 +554,30 @@ ptr_t cold_gc_frame; # endif /* - * Now traverse stacks. + * Now traverse stacks, and mark from register contents. + * These must be done last, since they can legitimately overflow + * the mark stack. */ -# if !defined(USE_GENERIC_PUSH_REGS) +# ifdef USE_GENERIC_PUSH_REGS + GC_generic_push_regs(cold_gc_frame); + /* Also pushes stack, so that we catch callee-save registers */ + /* saved inside the GC_push_regs frame. */ +# else + /* + * push registers - i.e., call GC_push_one(r) for each + * register contents r. + */ + GC_push_regs(); /* usually defined in machine_dep.c */ GC_push_current_stack(cold_gc_frame); /* In the threads case, this only pushes collector frames. */ - /* In the USE_GENERIC_PUSH_REGS case, this is done inside */ - /* GC_push_regs, so that we catch callee-save registers saved */ - /* inside the GC_push_regs frame. */ /* In the case of linux threads on IA64, the hot section of */ /* the main stack is marked here, but the register stack */ /* backing store is handled in the threads-specific code. */ # endif if (GC_push_other_roots != 0) (*GC_push_other_roots)(); /* In the threads case, this also pushes thread stacks. */ + /* Note that without interior pointer recognition lots */ + /* of stuff may have been pushed already, and this */ + /* should be careful about mark stack overflows. */ } diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c index 842d9a669bb..079a037a4ae 100644 --- a/boehm-gc/misc.c +++ b/boehm-gc/misc.c @@ -1,6 +1,7 @@ /* * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. + * Copyright (c) 1999-2001 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. @@ -97,6 +98,8 @@ GC_bool GC_quiet = 0; GC_bool GC_print_stats = 0; +GC_bool GC_print_back_height = 0; + #ifdef FIND_LEAK int GC_find_leak = 1; #else @@ -479,6 +482,12 @@ int sig; } #endif +#ifdef MSWIN32 + extern GC_bool GC_is_win32s(); +#else +# define GC_is_win32s() FALSE +#endif + void GC_init_inner() { # if !defined(THREADS) && defined(GC_ASSERTIONS) @@ -502,6 +511,22 @@ void GC_init_inner() if (0 != GETENV("GC_DONT_GC")) { GC_dont_gc = 1; } + if (0 != GETENV("GC_PRINT_BACK_HEIGHT")) { + GC_print_back_height = 1; + } + { + char * time_limit_string = GETENV("GC_PAUSE_TIME_TARGET"); + if (0 != time_limit_string) { + long time_limit; + if (time_limit_string != 0) time_limit = atol(time_limit_string); + if (time_limit < 5) { + WARN("GC_PAUSE_TIME_TARGET environment variable value too small " + "or bad syntax: Ignoring\n", 0); + } else { + GC_time_limit = time_limit; + } + } + } # ifdef UNIX_LIKE if (0 != GETENV("GC_LOOP_ON_ABORT")) { GC_set_and_save_fault_handler(looping_handler); @@ -611,8 +636,19 @@ void GC_init_inner() PCR_IL_Unlock(); GC_pcr_install(); # endif - /* Get black list set up */ - if (!GC_dont_precollect) GC_gcollect_inner(); +# if !defined(SMALL_CONFIG) + if (!GC_is_win32s() && 0 != GETENV("GC_ENABLE_INCREMENTAL")) { + GC_ASSERT(!GC_incremental); + GC_setpagesize(); +# ifndef GC_SOLARIS_THREADS + GC_dirty_init(); +# endif + GC_ASSERT(GC_words_allocd == 0) + GC_incremental = TRUE; + } +# endif /* !SMALL_CONFIG */ + /* Get black list set up and/or incrmental GC started */ + if (!GC_dont_precollect || GC_incremental) GC_gcollect_inner(); GC_is_initialized = TRUE; # ifdef STUBBORN_ALLOC GC_stubborn_init(); @@ -645,20 +681,14 @@ void GC_enable_incremental GC_PROTO(()) LOCK(); if (GC_incremental) goto out; GC_setpagesize(); -# ifdef MSWIN32 - { - extern GC_bool GC_is_win32s(); - - /* VirtualProtect is not functional under win32s. */ - if (GC_is_win32s()) goto out; - } -# endif /* MSWIN32 */ + if (GC_is_win32s()) goto out; # ifndef GC_SOLARIS_THREADS GC_dirty_init(); # endif if (!GC_is_initialized) { GC_init_inner(); } + if (GC_incremental) goto out; if (GC_dont_gc) { /* Can't easily do it. */ UNLOCK(); @@ -900,6 +930,13 @@ GC_CONST char * msg; #ifdef NEED_CALLINFO +#ifdef HAVE_BUILTIN_BACKTRACE +# include <execinfo.h> +# ifdef LINUX +# include <unistd.h> +# endif +#endif + void GC_print_callers (info) struct callinfo info[NFRAMES]; { @@ -925,7 +962,73 @@ struct callinfo info[NFRAMES]; GC_err_printf0("\n"); } # endif - GC_err_printf1("\t\t##PC##= 0x%X\n", info[i].ci_pc); +# if defined(HAVE_BUILTIN_BACKTRACE) && !defined(REDIRECT_MALLOC) + /* Unfortunately backtrace_symbols calls malloc, which makes */ + /* it dangersous if that has been redirected. */ + { + char **sym_name = + backtrace_symbols((void **)(&(info[i].ci_pc)), 1); + char *name = sym_name[0]; + GC_bool found_it = (strchr(name, '(') != 0); + FILE *pipe; +# ifdef LINUX + if (!found_it) { +# define EXE_SZ 100 + static char exe_name[EXE_SZ]; +# define CMD_SZ 200 + char cmd_buf[CMD_SZ]; +# define RESULT_SZ 200 + static char result_buf[RESULT_SZ]; + size_t result_len; + static GC_bool found_exe_name = FALSE; + static GC_bool will_fail = FALSE; + int ret_code; + /* Unfortunately, this is the common case for the */ + /* main executable. */ + /* Try to get it via a hairy and expensive scheme. */ + /* First we get the name of the executable: */ + if (will_fail) goto out; + if (!found_exe_name) { + ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ); + if (ret_code < 0 || ret_code >= EXE_SZ || exe_name[0] != '/') { + will_fail = TRUE; /* Dont try again. */ + goto out; + } + exe_name[ret_code] = '\0'; + found_exe_name = TRUE; + } + /* Then we use popen to start addr2line -e <exe> <addr> */ + /* There are faster ways to do this, but hopefully this */ + /* isn't time critical. */ + sprintf(cmd_buf, "/usr/bin/addr2line -e %s 0x%lx", exe_name, + (unsigned long)info[i].ci_pc); + pipe = popen(cmd_buf, "r"); + if (pipe < 0 || fgets(result_buf, RESULT_SZ, pipe) == 0) { + will_fail = TRUE; + goto out; + } + result_len = strlen(result_buf); + if (result_buf[result_len - 1] == '\n') --result_len; + if (result_buf[0] == '?' + || result_buf[result_len-2] == ':' + && result_buf[result_len-1] == '0') + goto out; + if (result_len < RESULT_SZ - 25) { + /* Add in hex address */ + sprintf(result_buf + result_len, " [0x%lx]", + (unsigned long)info[i].ci_pc); + } + name = result_buf; + pclose(pipe); + out: + } +# endif + GC_err_printf1("\t\t%s\n", name); + free(sym_name); + } +# else + GC_err_printf1("\t\t##PC##= 0x%lx\n", info[i].ci_pc); +# endif } } diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c index a84a80816f4..ae1125664e3 100644 --- a/boehm-gc/os_dep.c +++ b/boehm-gc/os_dep.c @@ -1101,6 +1101,9 @@ void GC_register_data_segments() GC_add_roots_inner(DATASTART, (char *)sbrk(0), FALSE); # else GC_add_roots_inner(DATASTART, (char *)(DATAEND), FALSE); +# if defined(DATASTART2) + GC_add_roots_inner(DATASTART2, (char *)(DATAEND2), FALSE); +# endif # endif # endif # if !defined(PCR) && (defined(NEXT) || defined(MACOSX)) @@ -1299,8 +1302,14 @@ void * os2_alloc(size_t bytes) SYSTEM_INFO GC_sysinfo; # endif - # ifdef MSWIN32 + +# ifdef USE_GLOBAL_ALLOC +# define GLOBAL_ALLOC_TEST 1 +# else +# define GLOBAL_ALLOC_TEST GC_win32s +# endif + word GC_n_heap_bases = 0; ptr_t GC_win32_get_mem(bytes) @@ -1308,7 +1317,7 @@ word bytes; { ptr_t result; - if (GC_win32s) { + if (GLOBAL_ALLOC_TEST) { /* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE. */ /* There are also unconfirmed rumors of other */ /* problems, so we dodge the issue. */ @@ -1742,11 +1751,18 @@ word n; { } -/* A call hints that h is about to be written. */ -/* May speed up some dirty bit implementations. */ +/* A call that: */ +/* I) hints that [h, h+nblocks) is about to be written. */ +/* II) guarantees that protection is removed. */ +/* (I) may speed up some dirty bit implementations. */ +/* (II) may be essential if we need to ensure that */ +/* pointer-free system call buffers in the heap are */ +/* not protected. */ /*ARGSUSED*/ -void GC_write_hint(h) +void GC_remove_protection(h, nblocks, is_ptrfree) struct hblk *h; +word nblocks; +GC_bool is_ptrfree; { } @@ -1849,12 +1865,16 @@ struct hblk *h; # endif #endif #if defined(LINUX) -# include <linux/version.h> -# if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA) || defined(IA64) +# if __GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 typedef struct sigcontext s_c; -# else - typedef struct sigcontext_struct s_c; -# endif +# else /* glibc < 2.2 */ +# include <linux/version.h> +# if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA) + typedef struct sigcontext s_c; +# else + typedef struct sigcontext_struct s_c; +# endif +# endif /* glibc < 2.2 */ # if defined(ALPHA) || defined(M68K) typedef void (* REAL_SIG_PF)(int, int, s_c *); # else @@ -2320,29 +2340,33 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ /* * We hold the allocation lock. We expect block h to be written - * shortly. + * shortly. Ensure that all pages cvontaining any part of the n hblks + * starting at h are no longer protected. If is_ptrfree is false, + * also ensure that they will subsequently appear to be dirty. */ -void GC_write_hint(h) +void GC_remove_protection(h, nblocks, is_ptrfree) struct hblk *h; +word nblocks; +GC_bool is_ptrfree; { - register struct hblk * h_trunc; - register unsigned i; - register GC_bool found_clean; + struct hblk * h_trunc; /* Truncated to page boundary */ + struct hblk * h_end; /* Page boundary following block end */ + struct hblk * current; + GC_bool found_clean; if (!GC_dirty_maintained) return; h_trunc = (struct hblk *)((word)h & ~(GC_page_size-1)); + h_end = (struct hblk *)(((word)(h + nblocks) + GC_page_size-1) + & ~(GC_page_size-1)); found_clean = FALSE; - for (i = 0; i < divHBLKSZ(GC_page_size); i++) { - register int index = PHT_HASH(h_trunc+i); + for (current = h_trunc; current < h_end; ++current) { + int index = PHT_HASH(current); - if (!get_pht_entry_from_index(GC_dirty_pages, index)) { - found_clean = TRUE; + if (!is_ptrfree || current < h || current >= h + nblocks) { async_set_pht_entry_from_index(GC_dirty_pages, index); } } - if (found_clean) { - UNPROTECT(h_trunc, GC_page_size); - } + UNPROTECT(h_trunc, (ptr_t)h_end - (ptr_t)h_trunc); } void GC_dirty_init() @@ -2461,18 +2485,77 @@ void GC_dirty_init() # endif } +int GC_incremental_protection_needs() +{ + if (GC_page_size == HBLKSIZE) { + return GC_PROTECTS_POINTER_HEAP; + } else { + return GC_PROTECTS_POINTER_HEAP | GC_PROTECTS_PTRFREE_HEAP; + } +} +#define HAVE_INCREMENTAL_PROTECTION_NEEDS +#define IS_PTRFREE(hhdr) ((hhdr)->hb_descr == 0) + +#define PAGE_ALIGNED(x) !((word)(x) & (GC_page_size - 1)) void GC_protect_heap() { ptr_t start; word len; + struct hblk * current; + struct hblk * current_start; /* Start of block to be protected. */ + struct hblk * limit; unsigned i; - + GC_bool protect_all = + (0 != (GC_incremental_protection_needs() & GC_PROTECTS_PTRFREE_HEAP)); for (i = 0; i < GC_n_heap_sects; i++) { start = GC_heap_sects[i].hs_start; len = GC_heap_sects[i].hs_bytes; - PROTECT(start, len); + if (protect_all) { + PROTECT(start, len); + } else { + GC_ASSERT(PAGE_ALIGNED(len)) + GC_ASSERT(PAGE_ALIGNED(start)) + current_start = current = (struct hblk *)start; + limit = (struct hblk *)(start + len); + while (current < limit) { + hdr * hhdr; + word nhblks; + GC_bool is_ptrfree; + + GC_ASSERT(PAGE_ALIGNED(current)); + GET_HDR(current, hhdr); + if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { + /* This can happen only if we're at the beginning of a */ + /* heap segment, and a block spans heap segments. */ + /* We will handle that block as part of the preceding */ + /* segment. */ + GC_ASSERT(current_start == current); + current_start = ++current; + continue; + } + if (HBLK_IS_FREE(hhdr)) { + GC_ASSERT(PAGE_ALIGNED(hhdr -> hb_sz)); + nhblks = divHBLKSZ(hhdr -> hb_sz); + is_ptrfree = TRUE; /* dirty on alloc */ + } else { + nhblks = OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz); + is_ptrfree = IS_PTRFREE(hhdr); + } + if (is_ptrfree) { + if (current_start < current) { + PROTECT(current_start, (ptr_t)current - (ptr_t)current_start); + } + current_start = (current += nhblks); + } else { + current += nhblks; + } + } + if (current_start < current) { + PROTECT(current_start, (ptr_t)current - (ptr_t)current_start); + } + } } } @@ -2529,7 +2612,7 @@ word len; register struct hblk *h; ptr_t obj_start; - if (!GC_incremental) return; + if (!GC_dirty_maintained) return; obj_start = GC_base(addr); if (obj_start == 0) return; if (GC_base(addr + len - 1) != obj_start) { @@ -2547,11 +2630,15 @@ word len; ((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE); } -#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(GC_LINUX_THREADS) \ +#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(THREADS) \ && !defined(GC_USE_LD_WRAP) -/* Replacement for UNIX system call. */ -/* Other calls that write to the heap */ -/* should be handled similarly. */ +/* Replacement for UNIX system call. */ +/* Other calls that write to the heap should be handled similarly. */ +/* Note that this doesn't work well for blocking reads: It will hold */ +/* tha allocation lock for the entur duration of the call. Multithreaded */ +/* clients should really ensure that it won't block, either by setting */ +/* the descriptor nonblocking, or by calling select or poll first, to */ +/* make sure that input is available. */ # if defined(__STDC__) && !defined(SUNOS4) # include <unistd.h> # include <sys/uio.h> @@ -2599,7 +2686,7 @@ word len; } #endif /* !MSWIN32 && !MSWINCE && !GC_LINUX_THREADS */ -#ifdef GC_USE_LD_WRAP +#if defined(GC_USE_LD_WRAP) && !defined(THREADS) /* We use the GNU ld call wrapping facility. */ /* This requires that the linker be invoked with "--wrap read". */ /* This can be done by passing -Wl,"--wrap read" to gcc. */ @@ -2738,8 +2825,10 @@ void GC_dirty_init() /* Ignore write hints. They don't help us here. */ /*ARGSUSED*/ -void GC_write_hint(h) +void GC_remove_protection(h, nblocks, is_ptrfree) struct hblk *h; +word nblocks; +GC_bool is_ptrfree; { } @@ -2947,15 +3036,24 @@ struct hblk *h; } /*ARGSUSED*/ -void GC_write_hint(h) +void GC_remove_protection(h, nblocks, is_ptrfree) struct hblk *h; +word nblocks; +GC_bool is_ptrfree; { - PCR_VD_WriteProtectDisable(h, HBLKSIZE); - PCR_VD_WriteProtectEnable(h, HBLKSIZE); + PCR_VD_WriteProtectDisable(h, nblocks*HBLKSIZE); + PCR_VD_WriteProtectEnable(h, nblocks*HBLKSIZE); } # endif /* PCR_VDB */ +# ifndef HAVE_INCREMENTAL_PROTECTION_NEEDS + int GC_incremental_protection_needs() + { + return GC_PROTECTS_NONE; + } +# endif /* !HAVE_INCREMENTAL_PROTECTION_NEEDS */ + /* * Call stack save code for debugging. * Should probably be in mach_dep.c, but that requires reorganization. @@ -2965,6 +3063,8 @@ struct hblk *h; /* long as the frame pointer is explicitly stored. In the case of gcc, */ /* compiler flags (e.g. -fomit-frame-pointer) determine whether it is. */ #if defined(I386) && defined(LINUX) && defined(SAVE_CALL_CHAIN) +# include <features.h> + struct frame { struct frame *fr_savfp; long fr_savpc; @@ -2974,6 +3074,8 @@ struct hblk *h; #if defined(SPARC) # if defined(LINUX) +# include <features.h> + struct frame { long fr_local[8]; long fr_arg[6]; @@ -3009,6 +3111,35 @@ struct hblk *h; /* Fill in the pc and argument information for up to NFRAMES of my */ /* callers. Ignore my frame and my callers frame. */ +#ifdef LINUX +# include <features.h> +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2 +# define HAVE_BUILTIN_BACKTRACE +# endif +#endif + +#if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \ + && defined(HAVE_BUILTIN_BACKTRACE) + +#include <execinfo.h> + +void GC_save_callers (info) +struct callinfo info[NFRAMES]; +{ + void * tmp_info[NFRAMES + 1]; + int npcs, i; +# define IGNORE_FRAMES 1 + + /* We retrieve NFRAMES+1 pc values, but discard the first, since it */ + /* points to our own frame. */ + GC_ASSERT(sizeof(struct callinfo) == sizeof(void *)); + npcs = backtrace((void **)tmp_info, NFRAMES + IGNORE_FRAMES); + BCOPY(tmp_info+IGNORE_FRAMES, info, (npcs - IGNORE_FRAMES) * sizeof(void *)); + for (i = npcs - IGNORE_FRAMES; i < NFRAMES; ++i) info[i].ci_pc = 0; +} + +#else /* No builtin backtrace; do it ourselves */ + #if (defined(OPENBSD) || defined(NETBSD)) && defined(SPARC) # define FR_SAVFP fr_fp # define FR_SAVPC fr_pc @@ -3055,6 +3186,8 @@ struct callinfo info[NFRAMES]; if (nframes < NFRAMES) info[nframes].ci_pc = 0; } +#endif /* No builtin backtrace */ + #endif /* SAVE_CALL_CHAIN */ #if defined(LINUX) && defined(__ELF__) && \ diff --git a/boehm-gc/reclaim.c b/boehm-gc/reclaim.c index 48db1e292a3..846215edb4f 100644 --- a/boehm-gc/reclaim.c +++ b/boehm-gc/reclaim.c @@ -631,47 +631,41 @@ COUNT_DECL ptr_t result = list; GC_ASSERT(GC_find_header((ptr_t)hbp) == hhdr); + GC_remove_protection(hbp, 1, (hhdr)->hb_descr == 0 /* Pointer-free? */); if (init) { switch(sz) { # if !defined(SMALL_CONFIG) && !defined(USE_MARK_BYTES) case 1: /* We now issue the hint even if GC_nearly_full returned */ /* DONT_KNOW. */ - GC_write_hint(hbp); result = GC_reclaim1(hbp, hhdr, list COUNT_ARG); break; case 2: - GC_write_hint(hbp); result = GC_reclaim_clear2(hbp, hhdr, list COUNT_ARG); break; case 4: - GC_write_hint(hbp); result = GC_reclaim_clear4(hbp, hhdr, list COUNT_ARG); break; # endif /* !SMALL_CONFIG && !USE_MARK_BYTES */ default: - GC_write_hint(hbp); result = GC_reclaim_clear(hbp, hhdr, sz, list COUNT_ARG); break; } } else { + GC_ASSERT((hhdr)->hb_descr == 0 /* Pointer-free block */); switch(sz) { # if !defined(SMALL_CONFIG) && !defined(USE_MARK_BYTES) case 1: - GC_write_hint(hbp); result = GC_reclaim1(hbp, hhdr, list COUNT_ARG); break; case 2: - GC_write_hint(hbp); result = GC_reclaim_uninit2(hbp, hhdr, list COUNT_ARG); break; case 4: - GC_write_hint(hbp); result = GC_reclaim_uninit4(hbp, hhdr, list COUNT_ARG); break; # endif /* !SMALL_CONFIG && !USE_MARK_BYTES */ default: - GC_write_hint(hbp); result = GC_reclaim_uninit(hbp, hhdr, sz, list COUNT_ARG); break; } diff --git a/boehm-gc/solaris_pthreads.c b/boehm-gc/solaris_pthreads.c index b07dd9b0a04..bd63e6c612c 100644 --- a/boehm-gc/solaris_pthreads.c +++ b/boehm-gc/solaris_pthreads.c @@ -88,8 +88,8 @@ GC_pthread_create(pthread_t *new_thread, } LOCK(); - if (!GC_thr_initialized) { - GC_thr_init(); + if (!GC_is_initialized) { + GC_init_inner(); } GC_multithreaded++; diff --git a/boehm-gc/solaris_threads.c b/boehm-gc/solaris_threads.c index 11b0e0375f6..2b520d3d085 100644 --- a/boehm-gc/solaris_threads.c +++ b/boehm-gc/solaris_threads.c @@ -16,7 +16,7 @@ */ /* Boehm, September 14, 1994 4:44 pm PDT */ -# if defined(GC_SOLARIS_THREADS) +# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS) # include "private/gc_priv.h" # include "private/solaris_threads.h" @@ -414,7 +414,6 @@ GC_bool GC_thr_initialized = FALSE; size_t GC_min_stack_sz; -size_t GC_page_sz; /* * stack_head is stored at the top of free stacks @@ -456,7 +455,7 @@ ptr_t GC_stack_alloc(size_t * stack_size) GC_stack_free_lists[index] = GC_stack_free_lists[index]->next; } else { #ifdef MMAP_STACKS - base = (ptr_t)mmap(0, search_sz + GC_page_sz, + base = (ptr_t)mmap(0, search_sz + GC_page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE |MAP_NORESERVE, GC_zfd, 0); if (base == (ptr_t)-1) @@ -465,27 +464,27 @@ ptr_t GC_stack_alloc(size_t * stack_size) return NULL; } - mprotect(base, GC_page_sz, PROT_NONE); - /* Should this use divHBLKSZ(search_sz + GC_page_sz) ? -- cf */ + mprotect(base, GC_page_size, PROT_NONE); + /* Should this use divHBLKSZ(search_sz + GC_page_size) ? -- cf */ GC_is_fresh((struct hblk *)base, divHBLKSZ(search_sz)); - base += GC_page_sz; + base += GC_page_size; #else - base = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_sz); + base = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_size); if (base == NULL) { *stack_size = 0; return NULL; } - base = (ptr_t)(((word)base + GC_page_sz) & ~(GC_page_sz - 1)); + base = (ptr_t)(((word)base + GC_page_size) & ~(GC_page_size - 1)); /* Protect hottest page to detect overflow. */ # ifdef SOLARIS23_MPROTECT_BUG_FIXED - mprotect(base, GC_page_sz, PROT_NONE); + mprotect(base, GC_page_size, PROT_NONE); # endif GC_is_fresh((struct hblk *)base, divHBLKSZ(search_sz)); - base += GC_page_sz; + base += GC_page_size; #endif } *stack_size = search_sz; @@ -665,8 +664,8 @@ void GC_my_stack_limits() /* original thread */ /* Empirically, what should be the stack page with lowest */ /* address is actually inaccessible. */ - stack_size = GC_get_orig_stack_size() - GC_page_sz; - stack = GC_stackbottom - stack_size + GC_page_sz; + stack_size = GC_get_orig_stack_size() - GC_page_size; + stack = GC_stackbottom - stack_size + GC_page_size; } else { stack = me -> stack; } @@ -704,7 +703,7 @@ void GC_push_all_stacks() top = p -> stack + p -> stack_size; } else { /* The original stack. */ - bottom = GC_stackbottom - GC_get_orig_stack_size() + GC_page_sz; + bottom = GC_stackbottom - GC_get_orig_stack_size() + GC_page_size; top = GC_stackbottom; } if ((word)sp > (word)bottom && (word)sp < (word)top) bottom = sp; @@ -789,7 +788,6 @@ void GC_thr_init(void) GC_thr_initialized = TRUE; GC_min_stack_sz = ((thr_min_stack() + 32*1024 + HBLKSIZE-1) & ~(HBLKSIZE - 1)); - GC_page_sz = sysconf(_SC_PAGESIZE); #ifdef MMAP_STACKS GC_zfd = open("/dev/zero", O_RDONLY); if (GC_zfd == -1) @@ -911,10 +909,7 @@ GC_thr_create(void *stack_base, size_t stack_size, void * stack = stack_base; LOCK(); - if (!GC_thr_initialized) - { - GC_thr_init(); - } + if (!GC_is_initialized) GC_init_inner(); GC_multithreaded++; if (stack == 0) { if (stack_size == 0) stack_size = 1024*1024; diff --git a/boehm-gc/sparc_mach_dep.s b/boehm-gc/sparc_mach_dep.s index 9831c6ca402..9f3a4b0a99d 100644 --- a/boehm-gc/sparc_mach_dep.s +++ b/boehm-gc/sparc_mach_dep.s @@ -9,13 +9,38 @@ .globl GC_push_regs GC_save_regs_in_stack: GC_push_regs: +#if defined(__arch64__) || defined(__sparcv9) + save %sp,-128,%sp + flushw + ret + restore %sp,2047+128,%o0 +#else /* 32 bit SPARC */ ta 0x3 ! ST_FLUSH_WINDOWS mov %sp,%o0 retl nop +#endif /* 32 bit SPARC */ +.GC_save_regs_in_stack_end: + .size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack + .globl GC_clear_stack_inner GC_clear_stack_inner: +#if defined(__arch64__) || defined(__sparcv9) + mov %sp,%o2 ! Save sp + add %sp,2047-8,%o3 ! p = sp+bias-8 + add %o1,-2047-192,%sp ! Move sp out of the way, + ! so that traps still work. + ! Includes some extra words + ! so we can be sloppy below. +loop: + stx %g0,[%o3] ! *(long *)p = 0 + cmp %o3,%o1 + bgu,pt %xcc, loop ! if (p > limit) goto loop + asm("add %o3,-8,%o3 ! p -= 8 (delay slot) + retl + mov %o2,%sp ! Restore sp., delay slot +#else /* 32 bit SPARC */ mov %sp,%o2 ! Save sp add %sp,-8,%o3 ! p = sp-8 clr %g1 ! [g0,g1] = 0 @@ -30,6 +55,10 @@ loop: add %o3,-8,%o3 ! p -= 8 (delay slot) retl mov %o2,%sp ! Restore sp., delay slot +#endif /* 32 bit SPARC */ +.GC_clear_stack_inner_end: + .size GC_clear_stack_inner,.GC_clear_stack_inner_end-GC_clear_stack_inner + diff --git a/boehm-gc/tests/test.c b/boehm-gc/tests/test.c index e8cc9763f44..7cb4d0c768f 100644 --- a/boehm-gc/tests/test.c +++ b/boehm-gc/tests/test.c @@ -20,7 +20,7 @@ # undef GC_BUILD -#ifdef DBG_HDRS_ALL +#if defined(DBG_HDRS_ALL) || defined(MAKE_BACK_GRAPH) # define GC_DEBUG #endif @@ -1340,7 +1340,7 @@ void SetMinimumStack(long minSize) # endif GC_INIT(); /* Only needed if gc is dynamic library. */ (void) GC_set_warn_proc(warn_proc); -# if defined(MPROTECT_VDB) || defined(PROC_VDB) +# if (defined(MPROTECT_VDB) || defined(PROC_VDB)) && !defined(MAKE_BACK_GRAPH) GC_enable_incremental(); (void) GC_printf0("Switched to incremental mode\n"); # if defined(MPROTECT_VDB) @@ -1571,7 +1571,9 @@ main() n_tests = 0; GC_INIT(); /* Only needed if gc is dynamic library. */ - GC_enable_incremental(); +# ifndef MAKE_BACK_GRAPH + GC_enable_incremental(); +# endif (void) GC_set_warn_proc(warn_proc); if (thr_keycreate(&fl_key, GC_free) != 0) { (void)GC_printf1("Key creation failed %lu\n", (unsigned long)code); @@ -1628,7 +1630,7 @@ main() pthread_attr_setstacksize(&attr, 1000000); # endif n_tests = 0; -# if defined(MPROTECT_VDB) && !defined(PARALLEL_MARK) &&!defined(REDIRECT_MALLOC) +# if defined(MPROTECT_VDB) && !defined(PARALLEL_MARK) &&!defined(REDIRECT_MALLOC) && !defined(MAKE_BACK_GRAPH) GC_enable_incremental(); (void) GC_printf0("Switched to incremental mode\n"); (void) GC_printf0("Emulating dirty bits with mprotect/signals\n"); diff --git a/boehm-gc/threadlibs.c b/boehm-gc/threadlibs.c index 991647ee849..99968a94a6c 100644 --- a/boehm-gc/threadlibs.c +++ b/boehm-gc/threadlibs.c @@ -10,13 +10,13 @@ int main() "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n"); # endif # if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \ - || defined(GC_FREEBSD_THREADS) + || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) printf("-lpthread\n"); # endif # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) printf("-lpthread -lrt\n"); # endif -# if defined(GC_SOLARIS_THREADS) +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) printf("-lthread -ldl\n"); # endif return 0; diff --git a/boehm-gc/version.h b/boehm-gc/version.h index d4e692345c5..96b7e64cbbe 100644 --- a/boehm-gc/version.h +++ b/boehm-gc/version.h @@ -1,6 +1,6 @@ #define GC_VERSION_MAJOR 6 #define GC_VERSION_MINOR 1 -#define GC_ALPHA_VERSION 1 +#define GC_ALPHA_VERSION 3 # define GC_NOT_ALPHA 0xff |