Imported GC 6.1 Alpha 3. Finally.

From-SVN: r49698
This commit is contained in:
Bryce McKinlay 2002-02-12 04:37:57 +00:00 committed by Bryce McKinlay
parent 005326029f
commit 79f777fd1e
40 changed files with 1287 additions and 512 deletions

View File

@ -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>

View File

@ -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:

View File

@ -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 \

View File

@ -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.

View File

@ -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. */

View File

@ -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. */

109
boehm-gc/config.guess vendored
View File

@ -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:*:*)

388
boehm-gc/config.sub vendored
View File

@ -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:

43
boehm-gc/configure vendored
View File

@ -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
@ -2844,12 +2851,6 @@ else
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"
@ -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

View File

@ -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)
;;

View File

@ -245,6 +245,9 @@ word integer;
LOCK();
# 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;
@ -274,6 +277,9 @@ word integer;
/* inconsistent while we're in the handler. */
# 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;

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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)))

View File

@ -838,3 +838,4 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void))
# endif
return(result);
}

View File

@ -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();

View File

@ -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)

View File

@ -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 */

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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: */

View File

@ -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)
/* 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 SAVE_CALL_CHAIN
# 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. */
# 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. */
# 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
# 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 */

View File

@ -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);

View File

@ -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. */

View File

@ -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");

View File

@ -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. */

View File

@ -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);

View File

@ -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))
{
@ -521,16 +521,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. */
}

View File

@ -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
}
}

View File

@ -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__) && \

View File

@ -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;
}

View File

@ -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++;

View File

@ -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;

View File

@ -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

View File

@ -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");

View File

@ -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;

View File

@ -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