diff -ru gcc-4.0.2.orig/boehm-gc/ChangeLog gcc-4.0.2/boehm-gc/ChangeLog --- gcc-4.0.2.orig/boehm-gc/ChangeLog 2005-09-21 05:54:54.000000000 +0200 +++ gcc-4.0.2/boehm-gc/ChangeLog 2006-03-10 19:39:29.000000000 +0100 @@ -1,6 +1,56 @@ -2005-09-20 Release Manager +2006-02-09 Tom Tromey - * GCC 4.0.2 released. + * pthread_support.c: Conditionally include dlfcn.h. + +2006-02-06 Jakub Jelinek + Anthony Green + Tom Tromey + + * include/gc_ext_config.h.in: Added GC_PTHREAD_SYM_VERSION. + * include/gc_config.h.in: Rebuilt. + * include/gc_pthread_redirects.h (pthread_create): Conditionally + define. + * pthread_support.c (pthread_create_): New global. + (constr): New function. + (pthread_create): Conditionally renamed. + * configure: Rebuilt. + * configure.ac (GC_PTHREAD_SYM_VERSION): Define. + +2006-02-04 Alan Modra + + * include/private/gc_locks.h (GC_test_and_set ): Don't + use broken 64-bit version. + +2006-01-25 Andreas Tobler + + * darwin_stop_world.c: Change inline asm instruction to ld as ldz + is wrong. + + * Makefile.am (asm_libgcjgc_sources): Rename to asm_libgcjgc_sources. + * Makefile.in: Regenerate. + +2006-01-25 Bryce McKinlay + + * include/private/gcconfig.h: Revert to GC 6.6 version, removing + all local changes. + +2006-01-24 Bryce McKinlay + + Import Boehm GC version 6.6. + +2006-01-24 David Ayers + + PR libobjc/13946 + * include/gc.h: Fix prototype declarations for bootstrap. + +2005-11-01 Bryce McKinlay + + * include/private/gc_priv.h: Increase MAX_ROOT_SETS to 1024. + +2005-09-15 Kazu Hirata + + * include/private/gc_locks.h (GC_test_and_set): Change the + constraint of the first operand to '0'. 2005-09-06 Tom Tromey @@ -12,23 +62,48 @@ * include/private/gcconfig.h (sh-linux): Use LINUX_STACKBOTTOM. -2005-07-07 Release Manager +2005-06-15 Andreas Tobler - * GCC 4.0.1 released. + * os_dep.c: Add FreeBSD/PowerPC bits. + (GC_SysVGetDataStart): Likewise. + * include/private/gcconfig.h: Likewise. 2005-05-25 Andrew Haley * include/private/gcconfig.h (HBLKSIZE): Define to 4096 on powerpc64-linux. -2005-04-20 Release Manager +2005-05-09 Mike Stump + + * configure: Regenerate. + +2005-04-19 Hans-Peter Nilsson + + * os_dep.c, include/private/gc_locks.h: Import CRIS port by + Simon Posnjak from gc6.4. + * include/private/gcconfig.h: Ditto. Add M32R note from gc6.4. - * GCC 4.0.0 released. +2005-04-17 David S. Miller + + * include/private/gcconfig.h (sparc-linux): Use LINUX_STACKBOTTOM. + * os_dep.c (GC_linux_stack_base): Check for bug present in some + Sparc glibc variants where __libc_stack_end is erroneously set + to "1". Fallback to procfs code in that case. + +2005-04-12 Mike Stump + + * configure: Regenerate. 2005-04-12 Richard Henderson * include/private/gcconfig.h (alpha-linux): Use LINUX_STACKBOTTOM. +2005-03-23 Mike Stump + + * darwin_stop_world.c: Update for -m64 multilib. + * include/private/gcconfig.h: Likewise. + * powerpc_darwin_mach_dep.s: Likewise. + 2005-03-01 Kelley Cook * Makefile.in, include/Makefile.in: Regenerate. diff -ru gcc-4.0.2.orig/boehm-gc/Makefile.am gcc-4.0.2/boehm-gc/Makefile.am --- gcc-4.0.2.orig/boehm-gc/Makefile.am 2004-11-05 02:51:48.000000000 +0100 +++ gcc-4.0.2/boehm-gc/Makefile.am 2006-03-10 19:39:29.000000000 +0100 @@ -12,33 +12,32 @@ noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la if POWERPC_DARWIN -asm_libgc_sources = powerpc_darwin_mach_dep.s +asm_libgcjgc_sources = powerpc_darwin_mach_dep.s else -asm_libgc_sources = +asm_libgcjgc_sources = endif -GC_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 aix_irix_threads.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 \ malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \ backgraph.c win32_threads.c \ pthread_support.c pthread_stop_world.c darwin_stop_world.c \ -$(asm_libgc_sources) +$(asm_libgcjgc_sources) + +libgcjgc_convenience_la_SOURCES = $(libgcjgc_la_SOURCES) EXTRA_DIST = alpha_mach_dep.S \ mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_darwin_mach_dep.s \ rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s -libgcjgc_la_SOURCES = $(GC_SOURCES) -libgcjgc_convenience_la_SOURCES = $(GC_SOURCES) - # Include THREADLIBS here to ensure that the correct versions of # linuxthread semaphore functions get linked: -libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) +libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) $(UNWINDLIBS) libgcjgc_la_DEPENDENCIES = @addobjs@ -libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir) +libgcjgc_la_LDFLAGS = -version-info 1:2:0 -rpath $(toolexeclibdir) libgcjgc_convenience_la_LIBADD = @addobjs@ libgcjgc_convenience_la_DEPENDENCIES = @addobjs@ @@ -48,7 +47,7 @@ check_PROGRAMS = gctest gctest_SOURCES = tests/test.c -gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS) +gctest_LDADD = ./libgcjgc.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) gctest_LDFLAGS = -shared-libgcc TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc TESTS = gctest diff -ru gcc-4.0.2.orig/boehm-gc/Makefile.direct gcc-4.0.2/boehm-gc/Makefile.direct --- gcc-4.0.2.orig/boehm-gc/Makefile.direct 2004-08-14 01:05:28.000000000 +0200 +++ gcc-4.0.2/boehm-gc/Makefile.direct 2006-03-10 19:39:29.000000000 +0100 @@ -36,7 +36,7 @@ # -DGC_LINUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC # To build the parallel collector in a static library on HP/UX, # add to the above: -# -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -D_POSIX_C_SOURCE=199506L +# -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -D_POSIX_C_SOURCE=199506L -mt # To build the thread-safe collector on Tru64, add to the above: # -pthread -DGC_OSF1_THREADS @@ -70,10 +70,11 @@ # 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. +# -DGC_OSF1_THREADS enables support for Tru64 pthreads. +# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. # Appeared to run into some underlying thread problems. -# -DGC_DARWIN_THREADS enables support for Mac OS X pthreads. Untested. +# -DGC_DARWIN_THREADS enables support for Mac OS X pthreads. +# -DGC_AIX_THREADS enables support for IBM AIX threads. # -DGC_DGUX386_THREADS enables support for DB/UX on I386 threads. # See README.DGUX386. # -DGC_WIN32_THREADS enables support for win32 threads. That makes sense @@ -233,8 +234,8 @@ # -DTHREAD_LOCAL_ALLOC defines GC_local_malloc(), GC_local_malloc_atomic() # and GC_local_gcj_malloc(). Needed for gc_gcj.h interface. These allocate # in a way that usually does not involve acquisition of a global lock. -# Currently requires -DGC_LINUX_THREADS, but should be easy to port to -# other pthreads environments. Recommended for multiprocessors. +# Currently works only on platforms such as Linux which use pthread_support.c. +# Recommended for multiprocessors. # -DUSE_COMPILER_TLS causes thread local allocation to use compiler-supported # "__thread" thread-local variables. This is the default in HP/UX. It # may help performance on recent Linux installations. (It failed for @@ -276,6 +277,10 @@ # -DPOINTER_SHIFT=n causes the collector to left shift candidate pointers # by the indicated amount before trying to interpret them. Applied # after POINTER_MASK. EXPERIMENTAL. See also the preceding macro. +# -DDARWIN_DONT_PARSE_STACK Causes the Darwin port to discover thread +# stack bounds in the same way as other pthread ports, without trying to +# walk the frames onthe stack. This is recommended only as a fallback +# for applications that don't support proper stack unwinding. # CXXFLAGS= $(CFLAGS) @@ -283,9 +288,9 @@ RANLIB= ranlib -OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o aix_irix_threads.o pthread_support.o pthread_stop_world.o darwin_stop_world.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o backgraph.o win32_threads.o +OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o pthread_support.o pthread_stop_world.o darwin_stop_world.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o backgraph.o win32_threads.o -CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c aix_irix_threads.c pthread_support.c pthread_stop_world.c darwin_stop_world.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c backgraph.c win32_threads.c +CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c pthread_support.c pthread_stop_world.c darwin_stop_world.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c backgraph.c win32_threads.c CORD_SRCS= cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c include/cord.h include/ec.h include/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC diff -ru gcc-4.0.2.orig/boehm-gc/Makefile.in gcc-4.0.2/boehm-gc/Makefile.in --- gcc-4.0.2.orig/boehm-gc/Makefile.in 2005-09-28 08:16:38.000000000 +0200 +++ gcc-4.0.2/boehm-gc/Makefile.in 2006-03-10 19:39:29.000000000 +0100 @@ -65,12 +65,13 @@ $(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \ $(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \ $(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \ - $(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \ - $(srcdir)/../ltmain.sh $(srcdir)/../config.guess \ - $(srcdir)/../config.sub + $(srcdir)/../compile $(srcdir)/../ltmain.sh \ + $(srcdir)/../config.guess $(srcdir)/../config.sub subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -83,24 +84,30 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @POWERPC_DARWIN_TRUE@am__objects_1 = powerpc_darwin_mach_dep.lo -am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \ +am_libgcjgc_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo checksums.lo \ dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \ - headers.lo aix_irix_threads.lo malloc.lo mallocx.lo mark.lo \ - mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo \ - pcr_interface.lo ptr_chck.lo real_malloc.lo reclaim.lo \ - solaris_pthreads.lo solaris_threads.lo specific.lo stubborn.lo \ - typd_mlc.lo backgraph.lo win32_threads.lo pthread_support.lo \ + headers.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \ + new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo ptr_chck.lo \ + real_malloc.lo reclaim.lo solaris_pthreads.lo \ + solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo \ + backgraph.lo win32_threads.lo pthread_support.lo \ pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1) -am_libgcjgc_la_OBJECTS = $(am__objects_2) libgcjgc_la_OBJECTS = $(am_libgcjgc_la_OBJECTS) +am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \ + dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \ + headers.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \ + new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo ptr_chck.lo \ + real_malloc.lo reclaim.lo solaris_pthreads.lo \ + solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo \ + backgraph.lo win32_threads.lo pthread_support.lo \ + pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1) am_libgcjgc_convenience_la_OBJECTS = $(am__objects_2) libgcjgc_convenience_la_OBJECTS = \ $(am_libgcjgc_convenience_la_OBJECTS) am__dirstamp = $(am__leading_dot)dirstamp am_gctest_OBJECTS = tests/test.$(OBJEXT) gctest_OBJECTS = $(am_gctest_OBJECTS) -gctest_DEPENDENCIES = ./libgcjgc.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) +gctest_DEPENDENCIES = ./libgcjgc.la $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_builddir)/include depcomp = am__depfiles_maybe = @@ -252,36 +259,35 @@ ACLOCAL_AMFLAGS = -I .. -I ../config SUBDIRS = include noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la -@POWERPC_DARWIN_FALSE@asm_libgc_sources = -@POWERPC_DARWIN_TRUE@asm_libgc_sources = powerpc_darwin_mach_dep.s -GC_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 aix_irix_threads.c \ +@POWERPC_DARWIN_FALSE@asm_libgcjgc_sources = +@POWERPC_DARWIN_TRUE@asm_libgcjgc_sources = powerpc_darwin_mach_dep.s +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 \ malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \ backgraph.c win32_threads.c \ pthread_support.c pthread_stop_world.c darwin_stop_world.c \ -$(asm_libgc_sources) +$(asm_libgcjgc_sources) +libgcjgc_convenience_la_SOURCES = $(libgcjgc_la_SOURCES) EXTRA_DIST = alpha_mach_dep.S \ mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_darwin_mach_dep.s \ rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s -libgcjgc_la_SOURCES = $(GC_SOURCES) -libgcjgc_convenience_la_SOURCES = $(GC_SOURCES) # Include THREADLIBS here to ensure that the correct versions of # linuxthread semaphore functions get linked: -libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) +libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) $(UNWINDLIBS) libgcjgc_la_DEPENDENCIES = @addobjs@ -libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir) +libgcjgc_la_LDFLAGS = -version-info 1:2:0 -rpath $(toolexeclibdir) libgcjgc_convenience_la_LIBADD = @addobjs@ libgcjgc_convenience_la_DEPENDENCIES = @addobjs@ AM_CXXFLAGS = @GC_CFLAGS@ AM_CFLAGS = @GC_CFLAGS@ gctest_SOURCES = tests/test.c -gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS) +gctest_LDADD = ./libgcjgc.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) gctest_LDFLAGS = -shared-libgcc TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc TESTS = gctest diff -ru gcc-4.0.2.orig/boehm-gc/aclocal.m4 gcc-4.0.2/boehm-gc/aclocal.m4 --- gcc-4.0.2.orig/boehm-gc/aclocal.m4 2005-09-28 08:16:38.000000000 +0200 +++ gcc-4.0.2/boehm-gc/aclocal.m4 2006-03-10 19:39:29.000000000 +0100 @@ -547,39 +547,6 @@ install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) -# -*- Autoconf -*- -# Copyright (C) 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - # Add --enable-maintainer-mode option to configure. # From Jim Meyering @@ -1168,5 +1135,7 @@ ]) # _AM_PROG_TAR m4_include([../config/acx.m4]) +m4_include([../config/depstand.m4]) +m4_include([../config/lead-dot.m4]) m4_include([../config/no-executables.m4]) m4_include([../libtool.m4]) diff -ru gcc-4.0.2.orig/boehm-gc/allchblk.c gcc-4.0.2/boehm-gc/allchblk.c --- gcc-4.0.2.orig/boehm-gc/allchblk.c 2005-02-09 22:33:01.000000000 +0100 +++ gcc-4.0.2/boehm-gc/allchblk.c 2006-03-10 19:39:29.000000000 +0100 @@ -285,8 +285,8 @@ GET_HDR(hhdr -> hb_prev, phdr); phdr -> hb_next = hhdr -> hb_next; } + FREE_ASSERT(GC_free_bytes[index] >= hhdr -> hb_sz); INCR_FREE_BYTES(index, - (signed_word)(hhdr -> hb_sz)); - FREE_ASSERT(GC_free_bytes[index] >= 0); if (0 != hhdr -> hb_next) { hdr * nhdr; GC_ASSERT(!IS_FORWARDING_ADDR_OR_NIL(NHDR(hhdr))); diff -ru gcc-4.0.2.orig/boehm-gc/alloc.c gcc-4.0.2/boehm-gc/alloc.c --- gcc-4.0.2.orig/boehm-gc/alloc.c 2004-08-28 02:41:39.000000000 +0200 +++ gcc-4.0.2/boehm-gc/alloc.c 2006-03-10 19:39:29.000000000 +0100 @@ -92,6 +92,16 @@ # include "version.h" +#if defined(SAVE_CALL_CHAIN) && \ + !(defined(REDIRECT_MALLOC) && defined(GC_HAVE_BUILTIN_BACKTRACE)) +# define SAVE_CALL_CHAIN_IN_GC + /* This is only safe if the call chain save mechanism won't end up */ + /* calling GC_malloc. The GNU C library documentation suggests */ + /* that backtrace doesn't use malloc, but at least the initial */ + /* call in some versions does seem to invoke the dynamic linker, */ + /* which uses malloc. */ +#endif + /* some more variables */ extern signed_word GC_mem_found; /* Number of reclaimed longwords */ @@ -196,7 +206,8 @@ /* had been reallocated this round. Finalization is user */ /* visible progress. And if we don't count this, we have */ /* stability problems for programs that finalize all objects. */ - result += GC_words_wasted; + if ((GC_words_wasted >> 3) < result) + result += GC_words_wasted; /* This doesn't reflect useful work. But if there is lots of */ /* new fragmentation, the same is probably true of the heap, */ /* and the collection will be correspondingly cheaper. */ @@ -221,6 +232,8 @@ { # define NWORDS 64 word frames[NWORDS]; + /* Some compilers will warn that frames was set but never used. */ + /* That's the whole idea ... */ register int i; for (i = 0; i < NWORDS; i++) frames[i] = 0; @@ -293,7 +306,7 @@ # endif if (GC_stopped_mark(GC_time_limit == GC_TIME_UNLIMITED? GC_never_stop_func : GC_timeout_stop_func)) { -# ifdef SAVE_CALL_CHAIN +# ifdef SAVE_CALL_CHAIN_IN_GC GC_save_callers(GC_last_stack); # endif GC_finish_collection(); @@ -358,7 +371,7 @@ } GC_invalidate_mark_state(); /* Flush mark stack. */ GC_clear_marks(); -# ifdef SAVE_CALL_CHAIN +# ifdef SAVE_CALL_CHAIN_IN_GC GC_save_callers(GC_last_stack); # endif GC_is_full_gc = TRUE; @@ -413,7 +426,7 @@ for (i = GC_deficit; i < GC_RATE*n; i++) { if (GC_mark_some((ptr_t)0)) { /* Need to finish a collection */ -# ifdef SAVE_CALL_CHAIN +# ifdef SAVE_CALL_CHAIN_IN_GC GC_save_callers(GC_last_stack); # endif # ifdef PARALLEL_MARK @@ -929,7 +942,7 @@ # endif expansion_slop = WORDS_TO_BYTES(min_words_allocd()) + 4*MAXHINCR*HBLKSIZE; if (GC_last_heap_addr == 0 && !((word)space & SIGNB) - || GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space) { + || (GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space)) { /* Assume the heap is growing up */ GC_greatest_plausible_heap_addr = (GC_PTR)GC_max((ptr_t)GC_greatest_plausible_heap_addr, @@ -992,7 +1005,7 @@ GC_bool ignore_off_page; { if (!GC_incremental && !GC_dont_gc && - (GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) { + ((GC_dont_expand && GC_words_allocd > 0) || GC_should_collect())) { GC_gcollect_inner(); } else { word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor) @@ -1001,6 +1014,9 @@ if (blocks_to_get > MAXHINCR) { word slop; + /* Get the minimum required to make it likely that we */ + /* can satisfy the current request in the presence of black- */ + /* listing. This will probably be more than MAXHINCR. */ if (ignore_off_page) { slop = 4; } else { diff -ru gcc-4.0.2.orig/boehm-gc/alpha_mach_dep.S gcc-4.0.2/boehm-gc/alpha_mach_dep.S --- gcc-4.0.2.orig/boehm-gc/alpha_mach_dep.S 2003-07-28 05:46:09.000000000 +0200 +++ gcc-4.0.2/boehm-gc/alpha_mach_dep.S 2006-03-10 19:39:29.000000000 +0100 @@ -1,4 +1,3 @@ - # $Id: alpha_mach_dep.s,v 1.2 1993/01/18 22:54:51 dosser Exp $ .arch ev6 .text @@ -12,13 +11,13 @@ .mask 0x04000000, 0 .frame $sp, 16, $26, 0 - # $0 integer result - # $1-$8 temp regs - not preserved cross calls - # $9-$15 call saved regs - # $16-$21 argument regs - not preserved cross calls - # $22-$28 temp regs - not preserved cross calls - # $29 global pointer - not preserved cross calls - # $30 stack pointer +/* $0 integer result */ +/* $1-$8 temp regs - not preserved cross calls */ +/* $9-$15 call saved regs */ +/* $16-$21 argument regs - not preserved cross calls */ +/* $22-$28 temp regs - not preserved cross calls */ +/* $29 global pointer - not preserved cross calls */ +/* $30 stack pointer */ # define call_push(x) \ mov x, $16; \ @@ -33,12 +32,12 @@ call_push($14) call_push($15) - # $f0-$f1 floating point results - # $f2-$f9 call saved regs - # $f10-$f30 temp regs - not preserved cross calls +/* $f0-$f1 floating point results */ +/* $f2-$f9 call saved regs */ +/* $f10-$f30 temp regs - not preserved cross calls */ - # Use the most efficient transfer method for this hardware. - # Bit 1 detects the FIX extension, which includes ftoit. + /* Use the most efficient transfer method for this hardware. */ + /* Bit 1 detects the FIX extension, which includes ftoit. */ amask 2, $0 bne $0, $use_stack diff -ru gcc-4.0.2.orig/boehm-gc/configure gcc-4.0.2/boehm-gc/configure --- gcc-4.0.2.orig/boehm-gc/configure 2005-09-28 08:16:38.000000000 +0200 +++ gcc-4.0.2/boehm-gc/configure 2006-03-10 19:39:29.000000000 +0100 @@ -1767,7 +1767,7 @@ # Define the identity of the package. PACKAGE=gc - VERSION=6.3 + VERSION=6.6 # Some tools Automake needs. @@ -4379,6 +4379,67 @@ # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +# find the maximum length of command line arguments +echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len" ; then + echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 +else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +fi + + # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) @@ -4712,7 +4773,7 @@ case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 4715 "configure"' > conftest.$ac_ext + echo '#line 4776 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6566,6 +6627,29 @@ fi +symver= +case "$target" in + *-*-linux* ) + cat > conftest.c < +void *tf (void *arg) { (void) arg; return NULL; } +int main (void) { pthread_t th; pthread_create (&th, NULL, tf, NULL); return 0; } +EOF + if $CC $CFLAGS -pthread -o conftest conftest.c > /dev/null 2>&1; then + symver=`readelf -s conftest 2> /dev/null | sed -n '/UND pthread_create@/{s/^.*@//;s/ .*$//;p;q}'` + fi + rm -f conftest conftest.c + ;; +esac +if test -n "$symver"; then + +cat >>confdefs.h <<_ACEOF +#define GC_PTHREAD_SYM_VERSION "$symver" +_ACEOF + +fi + + if test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then toolexecdir='$(exec_prefix)/$(target_noncanonical)' diff -ru gcc-4.0.2.orig/boehm-gc/configure.ac gcc-4.0.2/boehm-gc/configure.ac --- gcc-4.0.2.orig/boehm-gc/configure.ac 2005-02-16 05:10:41.000000000 +0100 +++ gcc-4.0.2/boehm-gc/configure.ac 2006-03-10 19:39:29.000000000 +0100 @@ -36,7 +36,7 @@ mkinstalldirs="`cd $ac_aux_dir && ${PWDCMD-pwd}`/mkinstalldirs" AC_SUBST(mkinstalldirs) -AM_INIT_AUTOMAKE(gc, 6.3, no-define) +AM_INIT_AUTOMAKE(gc, 6.6, no-define) # The autoconf 2.5x version of the no-executables hack. GCC_NO_EXECUTABLES @@ -450,6 +450,25 @@ AC_DEFINE(USE_MMAP, 1, [use MMAP instead of sbrk to get new memory]) fi +symver= +case "$target" in + *-*-linux* ) + cat > conftest.c < +void *tf (void *arg) { (void) arg; return NULL; } +int main (void) { pthread_t th; pthread_create (&th, NULL, tf, NULL); return 0; } +EOF + if $CC $CFLAGS -pthread -o conftest conftest.c > /dev/null 2>&1; then + symver=`readelf -s conftest 2> /dev/null | sed -n '/UND pthread_create@/{s/^.*@//;s/ .*$//;p;q}'` + fi + rm -f conftest conftest.c + ;; +esac +if test -n "$symver"; then + AC_DEFINE_UNQUOTED(GC_PTHREAD_SYM_VERSION, "$symver", [symbol version of pthread_create]) +fi + + if test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then toolexecdir='$(exec_prefix)/$(target_noncanonical)' diff -ru gcc-4.0.2.orig/boehm-gc/cord/cordprnt.c gcc-4.0.2/boehm-gc/cord/cordprnt.c --- gcc-4.0.2.orig/boehm-gc/cord/cordprnt.c 2004-08-14 01:05:31.000000000 +0200 +++ gcc-4.0.2/boehm-gc/cord/cordprnt.c 2006-03-10 19:39:28.000000000 +0100 @@ -59,7 +59,7 @@ register int result = 0; register int current_number = 0; register int saw_period = 0; - register int saw_number; + register int saw_number = 0; register int chars_so_far = 0; register char current; @@ -243,7 +243,7 @@ char * str = va_arg(args, char *); register char c; - while (c = *str++) { + while ((c = *str++)) { CORD_ec_append(result, c); } goto done; @@ -320,7 +320,7 @@ if (buf != result[0].ec_bufptr) { register char c; - while (c = *buf++) { + while ((c = *buf++)) { CORD_ec_append(result, c); } } else { diff -ru gcc-4.0.2.orig/boehm-gc/cord/cordtest.c gcc-4.0.2/boehm-gc/cord/cordtest.c --- gcc-4.0.2.orig/boehm-gc/cord/cordtest.c 2004-08-14 01:05:31.000000000 +0200 +++ gcc-4.0.2/boehm-gc/cord/cordtest.c 2006-03-10 19:39:28.000000000 +0100 @@ -221,7 +221,7 @@ if (CORD_cmp(result, result2) != 0)ABORT("CORD_sprintf goofed 5"); } -main() +int main() { # ifdef THINK_C printf("cordtest:\n"); diff -ru gcc-4.0.2.orig/boehm-gc/darwin_stop_world.c gcc-4.0.2/boehm-gc/darwin_stop_world.c --- gcc-4.0.2.orig/boehm-gc/darwin_stop_world.c 2004-08-14 01:05:29.000000000 +0200 +++ gcc-4.0.2/boehm-gc/darwin_stop_world.c 2006-04-08 11:54:52.000000000 +0200 @@ -1,5 +1,7 @@ #include "private/pthread_support.h" +/* This probably needs more porting work to ppc64. */ + # if defined(GC_DARWIN_THREADS) /* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple @@ -12,23 +14,33 @@ Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then it must set up a stack frame just like routines that call other routines." */ -#define PPC_RED_ZONE_SIZE 224 +#ifdef POWERPC +# if CPP_WORDSZ == 32 +# define PPC_RED_ZONE_SIZE 224 +# elif CPP_WORDSZ == 64 +# define PPC_RED_ZONE_SIZE 320 +# endif +#endif -/* Not 64-bit clean. Wait until Apple defines their 64-bit ABI */ typedef struct StackFrame { - unsigned int savedSP; - unsigned int savedCR; - unsigned int savedLR; - unsigned int reserved[2]; - unsigned int savedRTOC; + unsigned long savedSP; + unsigned long savedCR; + unsigned long savedLR; + unsigned long reserved[2]; + unsigned long savedRTOC; } StackFrame; - -unsigned int FindTopOfStack(unsigned int stack_start) { +unsigned long FindTopOfStack(unsigned int stack_start) { StackFrame *frame; if (stack_start == 0) { - __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); +# ifdef POWERPC +# if CPP_WORDSZ == 32 + __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); +# else + __asm__ volatile("ld %0,0(r1)" : "=r" (frame)); +# endif +# endif } else { frame = (StackFrame *)stack_start; } @@ -37,7 +49,7 @@ /* GC_printf1("FindTopOfStack start at sp = %p\n", frame); */ # endif do { - if (frame->savedSP == NULL) break; + if (frame->savedSP == 0) break; /* if there are no more stack frames, stop */ frame = (StackFrame*)frame->savedSP; @@ -53,9 +65,108 @@ /* GC_printf1("FindTopOfStack finish at sp = %p\n", frame); */ # endif - return (unsigned int)frame; + return (unsigned long)frame; } +#ifdef DARWIN_DONT_PARSE_STACK +void GC_push_all_stacks() { + int i; + kern_return_t r; + GC_thread p; + pthread_t me; + ptr_t lo, hi; +#if defined(POWERPC) + ppc_thread_state_t state; +#elif defined(I386) + i386_thread_state_t state; +#else +# error FIXME for non-x86 || ppc architectures +#endif + mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT; + + me = pthread_self(); + if (!GC_thr_initialized) GC_thr_init(); + + for(i=0;inext) { + if(p -> flags & FINISHED) continue; + if(pthread_equal(p->id,me)) { + lo = GC_approx_sp(); + } else { + /* Get the thread state (registers, etc) */ + r = thread_get_state( + p->stop_info.mach_thread, + MACHINE_THREAD_STATE, + (natural_t*)&state, + &thread_state_count); + if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); + +#if defined(I386) + lo = state.esp; + + GC_push_one(state.eax); + GC_push_one(state.ebx); + GC_push_one(state.ecx); + GC_push_one(state.edx); + GC_push_one(state.edi); + GC_push_one(state.esi); + GC_push_one(state.ebp); +#elif defined(POWERPC) + lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE); + + GC_push_one(state.r0); + GC_push_one(state.r2); + GC_push_one(state.r3); + GC_push_one(state.r4); + GC_push_one(state.r5); + GC_push_one(state.r6); + GC_push_one(state.r7); + GC_push_one(state.r8); + GC_push_one(state.r9); + GC_push_one(state.r10); + GC_push_one(state.r11); + GC_push_one(state.r12); + GC_push_one(state.r13); + GC_push_one(state.r14); + GC_push_one(state.r15); + GC_push_one(state.r16); + GC_push_one(state.r17); + GC_push_one(state.r18); + GC_push_one(state.r19); + GC_push_one(state.r20); + GC_push_one(state.r21); + GC_push_one(state.r22); + GC_push_one(state.r23); + GC_push_one(state.r24); + GC_push_one(state.r25); + GC_push_one(state.r26); + GC_push_one(state.r27); + GC_push_one(state.r28); + GC_push_one(state.r29); + GC_push_one(state.r30); + GC_push_one(state.r31); +#else +# error FIXME for non-x86 || ppc architectures +#endif + } /* p != me */ + if(p->flags & MAIN_THREAD) + hi = GC_stackbottom; + else + hi = p->stack_end; +#if DEBUG_THREADS + GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n", + (unsigned long) p -> id, + (unsigned long) lo, + (unsigned long) hi + ); +#endif + GC_push_all_stack(lo,hi); + } /* for(p=GC_threads[i]...) */ + } /* for(i=0;id_tag) != 0; dp++ ) { + /* FIXME: The DT_DEBUG header is not mandated by the */ + /* ELF spec. This code appears to be dependent on */ + /* idiosynchracies of older GNU tool chains. If this code */ + /* fails for you, the real problem is probably that it is */ + /* being used at all. You should be getting the */ + /* dl_iterate_phdr version. */ if( tag == DT_DEBUG ) { struct link_map *lm = ((struct r_debug *)(dp->d_un.d_ptr))->r_map; @@ -618,7 +631,8 @@ } for (i = 0; i < needed_sz; i++) { flags = addr_map[i].pr_mflags; - if ((flags & (MA_BREAK | MA_STACK | MA_PHYS)) != 0) goto irrelevant; + if ((flags & (MA_BREAK | MA_STACK | MA_PHYS + | MA_FETCHOP | MA_NOTCACHED)) != 0) goto irrelevant; if ((flags & (MA_READ | MA_WRITE)) != (MA_READ | MA_WRITE)) goto irrelevant; /* The latter test is empirically useless in very old Irix */ @@ -758,25 +772,27 @@ /* Should [start, start+len) be treated as a frame buffer */ /* and ignored? */ - /* Unfortunately, we currently have no real way to tell */ - /* automatically, and rely largely on user input. */ - /* FIXME: If we had more data on this phenomenon (e.g. */ - /* is start aligned to a MB multiple?) we should be able to */ - /* do better. */ + /* Unfortunately, we currently are not quite sure how to tell */ + /* this automatically, and rely largely on user input. */ + /* We expect that any mapping with type MEM_MAPPED (which */ + /* apparently excludes library data sections) can be safely */ + /* ignored. But we're too chicken to do that in this */ + /* version. */ /* Based on a very limited sample, it appears that: */ - /* - Frame buffer mappings appear as mappings of length */ - /* 2**n MB - 192K. (We guess the 192K can vary a bit.) */ - /* - Have a stating address at best 64K aligned. */ - /* I'd love more information about the mapping, since I */ - /* can't reproduce the problem. */ - static GC_bool is_frame_buffer(ptr_t start, size_t len) + /* - Frame buffer mappings appear as mappings of large */ + /* length, usually a bit less than a power of two. */ + /* - The definition of "a bit less" in the above cannot */ + /* be made more precise. */ + /* - Have a starting address at best 64K aligned. */ + /* - Have type == MEM_MAPPED. */ + static GC_bool is_frame_buffer(ptr_t start, size_t len, DWORD tp) { static GC_bool initialized = FALSE; # define MB (1024*1024) # define DEFAULT_FB_MB 15 # define MIN_FB_MB 3 - if (GC_disallow_ignore_fb) return FALSE; + if (GC_disallow_ignore_fb || tp != MEM_MAPPED) return FALSE; if (!initialized) { char * ignore_fb_string = GETENV("GC_IGNORE_FB"); @@ -869,7 +885,7 @@ * !is_frame_buffer(p, buf.RegionSize, buf.Type) * instead of just checking for MEM_IMAGE. * If something breaks, change it back. */ - && buf.Type == MEM_IMAGE) { + && buf.Type == MEM_IMAGE) { # ifdef DEBUG_VIRTUALQUERY GC_dump_meminfo(&buf); # endif @@ -1125,21 +1141,22 @@ static void GC_dyld_image_add(struct mach_header* hdr, unsigned long slide) { unsigned long start,end,i; const struct section *sec; + if (GC_no_dls) return; for(i=0;isize == 0) continue; - start = slide + sec->addr; - end = start + sec->size; -# ifdef DARWIN_DEBUG - GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n", + if(sec == NULL || sec->size == 0) continue; + start = slide + sec->addr; + end = start + sec->size; +# ifdef DARWIN_DEBUG + GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n", start,end,sec->size,GC_dyld_name_for_hdr(hdr)); -# endif +# endif GC_add_roots((char*)start,(char*)end); - } -# ifdef DARWIN_DEBUG - GC_print_static_roots(); -# endif + } +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif } /* This should never be called by a thread holding the lock */ @@ -1152,15 +1169,15 @@ if(sec == NULL || sec->size == 0) continue; start = slide + sec->addr; end = start + sec->size; -# ifdef DARWIN_DEBUG +# ifdef DARWIN_DEBUG GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n", start,end,sec->size,GC_dyld_name_for_hdr(hdr)); # endif GC_remove_roots((char*)start,(char*)end); } -# ifdef DARWIN_DEBUG - GC_print_static_roots(); -# endif +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif } void GC_register_dynamic_libraries() { diff -ru gcc-4.0.2.orig/boehm-gc/include/Makefile.in gcc-4.0.2/boehm-gc/include/Makefile.in --- gcc-4.0.2.orig/boehm-gc/include/Makefile.in 2005-03-02 00:28:07.000000000 +0100 +++ gcc-4.0.2/boehm-gc/include/Makefile.in 2006-03-10 19:39:28.000000000 +0100 @@ -43,6 +43,8 @@ $(srcdir)/gc_ext_config.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ diff -ru gcc-4.0.2.orig/boehm-gc/include/gc.h gcc-4.0.2/boehm-gc/include/gc.h --- gcc-4.0.2.orig/boehm-gc/include/gc.h 2005-01-02 04:35:57.000000000 +0100 +++ gcc-4.0.2/boehm-gc/include/gc.h 2006-03-10 19:39:28.000000000 +0100 @@ -55,7 +55,7 @@ # include # include "gc_config_macros.h" -# if defined(__STDC__) || defined(__cplusplus) +# if defined(__STDC__) || defined(__cplusplus) || defined(_AIX) # define GC_PROTO(args) args typedef void * GC_PTR; # define GC_CONST const @@ -152,7 +152,7 @@ /* ordered finalization. Default value is */ /* determined by JAVA_FINALIZATION macro. */ -GC_API void (* GC_finalizer_notifier)(); +GC_API void (* GC_finalizer_notifier) GC_PROTO((void)); /* Invoked by the collector when there are */ /* objects to be finalized. Invoked at most */ /* once per GC cycle. Never invoked unless */ @@ -214,7 +214,7 @@ /* least N/GC_free_space_divisor bytes between */ /* collections, where N is the heap size plus */ /* a rough estimate of the root set size. */ - /* Initially, GC_free_space_divisor = 4. */ + /* Initially, GC_free_space_divisor = 3. */ /* Increasing its value will use less space */ /* but more collection time. Decreasing it */ /* will appreciably decrease collection time */ @@ -340,6 +340,9 @@ /* the base of the user object. */ /* Return 0 if displaced_pointer doesn't point to within a valid */ /* object. */ +/* Note that a deallocated object in the garbage collected heap */ +/* may be considered valid, even if it has been deallocated with */ +/* GC_free. */ GC_API GC_PTR GC_base GC_PROTO((GC_PTR displaced_pointer)); /* Given a pointer to the base of an object, return its size in bytes. */ @@ -877,7 +880,7 @@ /* Safer assignment of a pointer to a nonstack location. */ #ifdef GC_DEBUG -# ifdef __STDC__ +# if defined(__STDC__) || defined(_AIX) # define GC_PTR_STORE(p, q) \ (*(void **)GC_is_visible(p) = GC_is_valid_displacement(q)) # else @@ -918,7 +921,7 @@ GC_PTR GC_malloc_many(size_t lb); #define GC_NEXT(p) (*(GC_PTR *)(p)) /* Retrieve the next element */ /* in returned list. */ -extern void GC_thr_init(); /* Needed for Solaris/X86 */ +extern void GC_thr_init GC_PROTO((void));/* Needed for Solaris/X86 */ #endif /* THREADS && !SRC_M3 */ @@ -972,12 +975,32 @@ # define GC_INIT() { extern end, etext; \ GC_noop(&end, &etext); } #else -# if defined(__CYGWIN32__) && defined(GC_DLL) || defined (_AIX) +# if defined(__CYGWIN32__) || defined (_AIX) /* * Similarly gnu-win32 DLLs need explicit initialization from * the main program, as does AIX. */ -# define GC_INIT() { GC_add_roots(DATASTART, DATAEND); } +# ifdef __CYGWIN32__ + extern int _data_start__[]; + extern int _data_end__[]; + extern int _bss_start__[]; + extern int _bss_end__[]; +# define GC_MAX(x,y) ((x) > (y) ? (x) : (y)) +# define GC_MIN(x,y) ((x) < (y) ? (x) : (y)) +# define GC_DATASTART ((GC_PTR) GC_MIN(_data_start__, _bss_start__)) +# define GC_DATAEND ((GC_PTR) GC_MAX(_data_end__, _bss_end__)) +# ifdef GC_DLL +# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); } +# else +# define GC_INIT() +# endif +# endif +# if defined(_AIX) + extern int _data[], _end[]; +# define GC_DATASTART ((GC_PTR)((ulong)_data)) +# define GC_DATAEND ((GC_PTR)((ulong)_end)) +# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); } +# endif # else # if defined(__APPLE__) && defined(__MACH__) || defined(GC_WIN32_THREADS) # define GC_INIT() { GC_init(); } diff -ru gcc-4.0.2.orig/boehm-gc/include/gc_config.h.in gcc-4.0.2/boehm-gc/include/gc_config.h.in --- gcc-4.0.2.orig/boehm-gc/include/gc_config.h.in 2005-02-16 05:10:42.000000000 +0100 +++ gcc-4.0.2/boehm-gc/include/gc_config.h.in 2006-03-10 19:39:28.000000000 +0100 @@ -45,6 +45,9 @@ /* support for Tru64 pthreads */ #undef GC_OSF1_THREADS +/* symbol version of pthread_create */ +#undef GC_PTHREAD_SYM_VERSION + /* support for Solaris pthreads */ #undef GC_SOLARIS_PTHREADS diff -ru gcc-4.0.2.orig/boehm-gc/include/gc_config_macros.h gcc-4.0.2/boehm-gc/include/gc_config_macros.h --- gcc-4.0.2.orig/boehm-gc/include/gc_config_macros.h 2004-08-14 01:05:32.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/gc_config_macros.h 2006-03-10 19:39:28.000000000 +0100 @@ -59,6 +59,10 @@ # define GC_DGUX386_THREADS # define GC_PTHREADS # endif +# if defined(_AIX) +# define GC_AIX_THREADS +# define GC_PTHREADS +# endif #endif /* GC_THREADS */ #if defined(GC_THREADS) && !defined(GC_PTHREADS) && \ diff -ru gcc-4.0.2.orig/boehm-gc/include/gc_cpp.h gcc-4.0.2/boehm-gc/include/gc_cpp.h --- gcc-4.0.2.orig/boehm-gc/include/gc_cpp.h 2004-08-14 01:05:32.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/gc_cpp.h 2006-03-10 19:39:28.000000000 +0100 @@ -74,7 +74,7 @@ collectable. See the interface gc.h for low-level facilities for handling such cycles of objects with clean-up. -The collector cannot guarrantee that it will find all inaccessible +The collector cannot guarantee that it will find all inaccessible objects. In practice, it finds almost all of them. diff -ru gcc-4.0.2.orig/boehm-gc/include/gc_ext_config.h.in gcc-4.0.2/boehm-gc/include/gc_ext_config.h.in --- gcc-4.0.2.orig/boehm-gc/include/gc_ext_config.h.in 2005-01-02 04:35:57.000000000 +0100 +++ gcc-4.0.2/boehm-gc/include/gc_ext_config.h.in 2006-03-10 19:39:28.000000000 +0100 @@ -3,3 +3,5 @@ is used by libjava/include/boehm-gc.h. */ #undef THREAD_LOCAL_ALLOC + +#undef GC_PTHREAD_SYM_VERSION diff -ru gcc-4.0.2.orig/boehm-gc/include/gc_pthread_redirects.h gcc-4.0.2/boehm-gc/include/gc_pthread_redirects.h --- gcc-4.0.2.orig/boehm-gc/include/gc_pthread_redirects.h 2003-07-28 06:18:23.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/gc_pthread_redirects.h 2006-03-10 19:39:28.000000000 +0100 @@ -68,7 +68,9 @@ # undef pthread_detach #endif +#ifndef GC_PTHREAD_SYM_VERSION # define pthread_create GC_pthread_create +#endif # define pthread_join GC_pthread_join # define pthread_detach GC_pthread_detach diff -ru gcc-4.0.2.orig/boehm-gc/include/new_gc_alloc.h gcc-4.0.2/boehm-gc/include/new_gc_alloc.h --- gcc-4.0.2.orig/boehm-gc/include/new_gc_alloc.h 2004-08-14 01:05:33.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/new_gc_alloc.h 2006-03-10 19:39:28.000000000 +0100 @@ -109,7 +109,7 @@ enum { GC_word_alignment = GC_byte_alignment/GC_bytes_per_word }; inline void * &GC_obj_link(void * p) -{ return *(void **)p; } +{ return *reinterpret_cast(p); } // Compute a number of words >= n+1 bytes. // The +1 allows for pointers one past the end. @@ -228,7 +228,7 @@ } else { flh = GC_objfreelist_ptr + nwords; GC_obj_link(p) = *flh; - memset((char *)p + GC_bytes_per_word, 0, + memset(reinterpret_cast(p) + GC_bytes_per_word, 0, GC_bytes_per_word * (nwords - 1)); *flh = p; GC_aux::GC_mem_recently_freed += nwords; @@ -352,9 +352,9 @@ public: \ static T *allocate(size_t n) \ { return 0 == n? 0 : \ - (T*) alloc::ptr_free_allocate(n * sizeof (T)); } \ + reinterpret_cast(alloc::ptr_free_allocate(n * sizeof (T))); } \ static T *allocate(void) \ - { return (T*) alloc::ptr_free_allocate(sizeof (T)); } \ + { return reinterpret_cast(alloc::ptr_free_allocate(sizeof (T))); } \ static void deallocate(T *p, size_t n) \ { if (0 != n) alloc::ptr_free_deallocate(p, n * sizeof (T)); } \ static void deallocate(T *p) \ diff -ru gcc-4.0.2.orig/boehm-gc/include/private/gc_hdrs.h gcc-4.0.2/boehm-gc/include/private/gc_hdrs.h --- gcc-4.0.2.orig/boehm-gc/include/private/gc_hdrs.h 2003-07-28 06:18:23.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/private/gc_hdrs.h 2006-03-10 19:39:28.000000000 +0100 @@ -108,7 +108,7 @@ /* Analogous to GET_HDR, except that in the case of large objects, it */ /* Returns the header for the object beginning, and updates p. */ -/* Returns &GC_bad_header instead of 0. All of this saves a branch */ +/* Returns GC_invalid_header instead of 0. All of this saves a branch */ /* in the fast path. */ # define HC_GET_HDR(p, hhdr, source) \ { \ diff -ru gcc-4.0.2.orig/boehm-gc/include/private/gc_locks.h gcc-4.0.2/boehm-gc/include/private/gc_locks.h --- gcc-4.0.2.orig/boehm-gc/include/private/gc_locks.h 2003-07-28 06:18:23.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/private/gc_locks.h 2006-03-10 19:39:28.000000000 +0100 @@ -139,6 +139,25 @@ # define GC_TEST_AND_SET_DEFINED # endif # if defined(POWERPC) +# if 0 /* CPP_WORDSZ == 64 totally broken to use int locks with ldarx */ + inline static int GC_test_and_set(volatile unsigned int *addr) { + unsigned long oldval; + unsigned long temp = 1; /* locked value */ + + __asm__ __volatile__( + "1:\tldarx %0,0,%3\n" /* load and reserve */ + "\tcmpdi %0, 0\n" /* if load is */ + "\tbne 2f\n" /* non-zero, return already set */ + "\tstdcx. %2,0,%1\n" /* else store conditional */ + "\tbne- 1b\n" /* retry if lost reservation */ + "\tsync\n" /* import barrier */ + "2:\t\n" /* oldval is zero if we set */ + : "=&r"(oldval), "=p"(addr) + : "r"(temp), "1"(addr) + : "cr0","memory"); + return (int)oldval; + } +# else inline static int GC_test_and_set(volatile unsigned int *addr) { int oldval; int temp = 1; /* locked value */ @@ -156,12 +175,13 @@ : "cr0","memory"); return oldval; } -# define GC_TEST_AND_SET_DEFINED - inline static void GC_clear(volatile unsigned int *addr) { - __asm__ __volatile__("eieio" : : : "memory"); - *(addr) = 0; - } -# define GC_CLEAR_DEFINED +# endif +# define GC_TEST_AND_SET_DEFINED + inline static void GC_clear(volatile unsigned int *addr) { + __asm__ __volatile__("lwsync" : : : "memory"); + *(addr) = 0; + } +# define GC_CLEAR_DEFINED # endif # if defined(ALPHA) inline static int GC_test_and_set(volatile unsigned int * addr) @@ -209,12 +229,36 @@ /* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */ __asm__ __volatile__("swp %0, %1, [%2]" : "=r"(oldval) - : "r"(1), "r"(addr) + : "0"(1), "r"(addr) : "memory"); return oldval; } # define GC_TEST_AND_SET_DEFINED # endif /* ARM32 */ +# ifdef CRIS + inline static int GC_test_and_set(volatile unsigned int *addr) { + /* Ripped from linuxthreads/sysdeps/cris/pt-machine.h. */ + /* Included with Hans-Peter Nilsson's permission. */ + register unsigned long int ret; + + /* Note the use of a dummy output of *addr to expose the write. + * The memory barrier is to stop *other* writes being moved past + * this code. + */ + __asm__ __volatile__("clearf\n" + "0:\n\t" + "movu.b [%2],%0\n\t" + "ax\n\t" + "move.b %3,[%2]\n\t" + "bwf 0b\n\t" + "clearf" + : "=&r" (ret), "=m" (*addr) + : "r" (addr), "r" ((int) 1), "m" (*addr) + : "memory"); + return ret; + } +# define GC_TEST_AND_SET_DEFINED +# endif /* CRIS */ # ifdef S390 inline static int GC_test_and_set(volatile unsigned int *addr) { int ret; @@ -258,6 +302,8 @@ # define GC_test_and_set(addr) test_and_set((void *)addr,1) # endif # else +# include +# include # define GC_test_and_set(addr) __test_and_set32((void *)addr,1) # define GC_clear(addr) __lock_release(addr); # define GC_CLEAR_DEFINED @@ -330,7 +376,7 @@ # endif # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) + && !defined(GC_WIN32_THREADS) # define NO_THREAD (pthread_t)(-1) # include # if defined(PARALLEL_MARK) @@ -377,6 +423,29 @@ # if defined(POWERPC) # if !defined(GENERIC_COMPARE_AND_SWAP) +# if CPP_WORDSZ == 64 + /* Returns TRUE if the comparison succeeded. */ + inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, + GC_word old, GC_word new_val) + { + unsigned long result, dummy; + __asm__ __volatile__( + "1:\tldarx %0,0,%5\n" + "\tcmpd %0,%4\n" + "\tbne 2f\n" + "\tstdcx. %3,0,%2\n" + "\tbne- 1b\n" + "\tsync\n" + "\tli %1, 1\n" + "\tb 3f\n" + "2:\tli %1, 0\n" + "3:\t\n" + : "=&r" (dummy), "=r" (result), "=p" (addr) + : "r" (new_val), "r" (old), "2"(addr) + : "cr0","memory"); + return (GC_bool) result; + } +# else /* Returns TRUE if the comparison succeeded. */ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, GC_word old, GC_word new_val) @@ -398,6 +467,7 @@ : "cr0","memory"); return (GC_bool) result; } +# endif # endif /* !GENERIC_COMPARE_AND_SWAP */ inline static void GC_memory_barrier() { @@ -574,33 +644,6 @@ extern pthread_t GC_mark_lock_holder; # endif # endif /* GC_PTHREADS with linux_threads.c implementation */ -# if defined(GC_IRIX_THREADS) -# include - /* This probably should never be included, but I can't test */ - /* on Irix anymore. */ -# include - - extern volatile unsigned int GC_allocate_lock; - /* This is not a mutex because mutexes that obey the (optional) */ - /* POSIX scheduling rules are subject to convoys in high contention */ - /* applications. This is basically a spin lock. */ - extern pthread_t GC_lock_holder; - extern void GC_lock(void); - /* Allocation lock holder. Only set if acquired by client through */ - /* GC_call_with_alloc_lock. */ -# define SET_LOCK_HOLDER() GC_lock_holder = pthread_self() -# define NO_THREAD (pthread_t)(-1) -# define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD -# define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self())) -# define LOCK() { if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); } -# define UNLOCK() GC_clear(&GC_allocate_lock); - extern VOLATILE GC_bool GC_collecting; -# define ENTER_GC() \ - { \ - GC_collecting = 1; \ - } -# define EXIT_GC() GC_collecting = 0; -# endif /* GC_IRIX_THREADS */ # if defined(GC_WIN32_THREADS) # if defined(GC_PTHREADS) # include diff -ru gcc-4.0.2.orig/boehm-gc/include/private/gc_priv.h gcc-4.0.2/boehm-gc/include/private/gc_priv.h --- gcc-4.0.2.orig/boehm-gc/include/private/gc_priv.h 2005-02-16 05:10:42.000000000 +0100 +++ gcc-4.0.2/boehm-gc/include/private/gc_priv.h 2006-03-10 19:39:28.000000000 +0100 @@ -262,17 +262,6 @@ /* */ /*********************************/ -#ifdef SAVE_CALL_CHAIN - -/* Fill in the pc and argument information for up to NFRAMES of my */ -/* callers. Ignore my frame and my callers frame. */ -struct callinfo; -void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES])); - -void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES])); - -#endif - #ifdef NEED_CALLINFO struct callinfo { word ci_pc; /* Caller, not callee, pc */ @@ -286,6 +275,16 @@ }; #endif +#ifdef SAVE_CALL_CHAIN + +/* Fill in the pc and argument information for up to NFRAMES of my */ +/* callers. Ignore my frame and my callers frame. */ +void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES])); + +void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES])); + +#endif + /*********************************/ /* */ @@ -760,17 +759,9 @@ # ifdef LARGE_CONFIG # define MAX_ROOT_SETS 4096 # else -# ifdef PCR -# define MAX_ROOT_SETS 1024 -# else -# if defined(MSWIN32) || defined(MSWINCE) -# define MAX_ROOT_SETS 1024 - /* Under NT, we add only written pages, which can result */ - /* in many small root sets. */ -# else -# define MAX_ROOT_SETS 256 -# endif -# endif + /* GCJ LOCAL: MAX_ROOT_SETS increased to permit more shared */ + /* libraries to be loaded. */ +# define MAX_ROOT_SETS 1024 # endif # define MAX_EXCLUSIONS (MAX_ROOT_SETS/4) diff -ru gcc-4.0.2.orig/boehm-gc/include/private/gcconfig.h gcc-4.0.2/boehm-gc/include/private/gcconfig.h --- gcc-4.0.2.orig/boehm-gc/include/private/gcconfig.h 2005-09-06 16:21:25.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/private/gcconfig.h 2006-03-10 19:39:28.000000000 +0100 @@ -55,7 +55,7 @@ # endif /* And one for FreeBSD: */ -# if defined(__FreeBSD__) +# if defined(__FreeBSD__) && !defined(FREEBSD) # define FREEBSD # endif @@ -97,6 +97,10 @@ # define ARM32 # define mach_type_known # endif +# if defined(NETBSD) && defined(__sh__) +# define SH +# define mach_type_known +# endif # if defined(vax) # define VAX # ifdef ultrix @@ -127,6 +131,9 @@ # endif # endif # endif /* !LINUX */ +# if defined(__NetBSD__) && defined(__MIPSEL__) +# undef ULTRIX +# endif # define mach_type_known # endif # if defined(DGUX) && (defined(i386) || defined(__i386__)) @@ -167,7 +174,7 @@ # define mach_type_known # endif # if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \ - && !defined(__OpenBSD__) && !(__NetBSD__) + && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) # define SPARC # define DRSNX # define mach_type_known @@ -198,14 +205,16 @@ # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \ || defined(hppa) || defined(__hppa__) # define HP_PA -# ifndef LINUX +# if !defined(LINUX) && !defined(HPUX) # define HPUX # endif # define mach_type_known # endif # if defined(__ia64) && defined(_HPUX_SOURCE) # define IA64 -# define HPUX +# ifndef HPUX +# define HPUX +# endif # define mach_type_known # endif # if defined(__BEOS__) && defined(_X86_) @@ -229,7 +238,18 @@ # define ARM32 # define mach_type_known # endif -# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || defined(powerpc64) || defined(__powerpc64__)) +# if defined(LINUX) && defined(__cris__) +# ifndef CRIS +# define CRIS +# endif +# define mach_type_known +# endif +# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || \ + defined(powerpc64) || defined(__powerpc64__)) +# define POWERPC +# define mach_type_known +# endif +# if defined(FREEBSD) && (defined(powerpc) || defined(__powerpc__)) # define POWERPC # define mach_type_known # endif @@ -277,16 +297,16 @@ # define MACOS # define mach_type_known # endif -# if defined(macosx) || \ - defined(__APPLE__) && defined(__MACH__) && defined(__ppc__) -# define DARWIN +# if defined(macosx) || (defined(__APPLE__) && defined(__MACH__)) +# define DARWIN +# if defined(__ppc__) || defined(__ppc64__) # define POWERPC # define mach_type_known -# endif -# if defined(__APPLE__) && defined(__MACH__) && defined(__i386__) -# define DARWIN +# endif +# if defined(__i386__) # define I386 - --> Not really supported, but at least we recognize it. +# define mach_type_known +# endif # endif # if defined(NeXT) && defined(mc68000) # define M68K @@ -315,6 +335,10 @@ # define X86_64 # define mach_type_known # endif +# if defined(FREEBSD) && defined(__sparc__) +# define SPARC +# define mach_type_known +#endif # if defined(bsdi) && (defined(i386) || defined(__i386__)) # define I386 # define BSDI @@ -475,17 +499,22 @@ /* POWERPC ==> IBM/Apple PowerPC */ /* (MACOS(<=9),DARWIN(incl.MACOSX),*/ /* LINUX, NETBSD, NOSYS variants) */ + /* Handles 32 and 64-bit variants. */ + /* AIX should be handled here, but */ + /* that's called an RS6000. */ + /* CRIS ==> Axis Etrax */ + /* M32R ==> Renesas M32R */ /* * For each architecture and OS, the following need to be defined: * - * CPP_WORD_SZ is a simple integer constant representing the word size. + * CPP_WORDSZ is a simple integer constant representing the word size. * in bits. We assume byte addressibility, where a byte has 8 bits. - * We also assume CPP_WORD_SZ is either 32 or 64. + * We also assume CPP_WORDSZ is either 32 or 64. * (We care about the length of pointers, not hardware * bus widths. Thus a 64 bit processor with a C compiler that uses - * 32 bit pointers should use CPP_WORD_SZ of 32, not 64. Default is 32.) + * 32 bit pointers should use CPP_WORDSZ of 32, not 64. Default is 32.) * * MACH_TYPE is a string representation of the machine type. * OS_TYPE is analogous for the OS. @@ -602,7 +631,8 @@ */ # if defined(__GNUC__) && ((__GNUC__ >= 3) || \ (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \ - && !defined(__INTEL_COMPILER) + && !defined(__INTEL_COMPILER) \ + && !defined(__PATHCC__) # define HAVE_BUILTIN_UNWIND_INIT # endif @@ -638,8 +668,7 @@ # define OS_TYPE "LINUX" # define STACKBOTTOM ((ptr_t)0xf0000000) # define USE_GENERIC_PUSH_REGS -# define USE_MMAP - /* We never got around to the assembly version. */ + /* We never got around to the assembly version. */ /* # define MPROTECT_VDB - Reported to not work 9/17/01 */ # ifdef __ELF__ # define DYNAMIC_LOADING @@ -727,7 +756,7 @@ # endif # endif -# ifdef POWERPC +# if defined(POWERPC) # define MACH_TYPE "POWERPC" # ifdef MACOS # define ALIGNMENT 2 /* Still necessary? Could it be 4? */ @@ -740,10 +769,12 @@ # define DATAEND /* not needed */ # endif # ifdef LINUX -# if (defined (powerpc64) || defined(__powerpc64__)) +# if defined(__powerpc64__) # define ALIGNMENT 8 # define CPP_WORDSZ 64 -# define HBLKSIZE 4096 +# ifndef HBLKSIZE +# define HBLKSIZE 4096 +# endif # else # define ALIGNMENT 4 # endif @@ -757,7 +788,12 @@ # define DATAEND (_end) # endif # ifdef DARWIN -# define ALIGNMENT 4 +# ifdef __ppc64__ +# define ALIGNMENT 8 +# define CPP_WORDSZ 64 +# else +# define ALIGNMENT 4 +# endif # define OS_TYPE "DARWIN" # define DYNAMIC_LOADING /* XXX: see get_end(3), get_etext() and get_end() should not be used. @@ -769,8 +805,10 @@ # define USE_MMAP_ANON # define USE_ASM_PUSH_REGS /* This is potentially buggy. It needs more testing. See the comments in - os_dep.c */ -# define MPROTECT_VDB + os_dep.c. It relies on threads to track writes. */ +# ifdef GC_DARWIN_THREADS +/* # define MPROTECT_VDB -- diabled for now. May work for some apps. */ +# endif # include # define GETPAGESIZE() getpagesize() # if defined(USE_PPC_PREFETCH) && defined(__GNUC__) @@ -784,6 +822,22 @@ should be looked into some more */ # define NO_PTHREAD_TRYLOCK # endif +# ifdef FREEBSD +# define ALIGNMENT 4 +# define OS_TYPE "FREEBSD" +# ifndef GC_FREEBSD_THREADS +# define MPROTECT_VDB +# endif +# define SIG_SUSPEND SIGUSR1 +# define SIG_THR_RESTART SIGUSR2 +# define FREEBSD_STACKBOTTOM +# ifdef __ELF__ +# define DYNAMIC_LOADING +# endif + extern char etext[]; + extern char * GC_FreeBSDGetDataStart(); +# define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext) +# endif # ifdef NETBSD # define ALIGNMENT 4 # define OS_TYPE "NETBSD" @@ -941,6 +995,23 @@ # define DATASTART ((ptr_t)(etext)) # endif # endif +# ifdef FREEBSD +# define OS_TYPE "FREEBSD" +# define SIG_SUSPEND SIGUSR1 +# define SIG_THR_RESTART SIGUSR2 +# define FREEBSD_STACKBOTTOM +# ifdef __ELF__ +# define DYNAMIC_LOADING +# endif + extern char etext[]; + extern char edata[]; + extern char end[]; +# define NEED_FIND_LIMIT +# define DATASTART ((ptr_t)(&etext)) +# define DATAEND (GC_find_limit (DATASTART, TRUE)) +# define DATASTART2 ((ptr_t)(&edata)) +# define DATAEND2 ((ptr_t)(&end)) +# endif # endif # ifdef I386 @@ -1124,26 +1195,8 @@ # endif # ifdef CYGWIN32 # define OS_TYPE "CYGWIN32" - extern int _data_start__[]; - extern int _data_end__[]; - extern int _bss_start__[]; - extern int _bss_end__[]; - /* For binutils 2.9.1, we have */ - /* DATASTART = _data_start__ */ - /* DATAEND = _bss_end__ */ - /* whereas for some earlier versions it was */ - /* DATASTART = _bss_start__ */ - /* DATAEND = _data_end__ */ - /* To get it right for both, we take the */ - /* minumum/maximum of the two. */ -# ifndef MAX -# define MAX(x,y) ((x) > (y) ? (x) : (y)) -# endif -# ifndef MIN -# define MIN(x,y) ((x) < (y) ? (x) : (y)) -# endif -# define DATASTART ((ptr_t) MIN(_data_start__, _bss_start__)) -# define DATAEND ((ptr_t) MAX(_data_end__, _bss_end__)) +# define DATASTART ((ptr_t)GC_DATASTART) /* From gc.h */ +# define DATAEND ((ptr_t)GC_DATAEND) # undef STACK_GRAN # define STACK_GRAN 0x10000 # define HEURISTIC1 @@ -1249,6 +1302,29 @@ /* # define MPROTECT_VDB Not quite working yet? */ # define DYNAMIC_LOADING # endif +# ifdef DARWIN +# define OS_TYPE "DARWIN" +# define DARWIN_DONT_PARSE_STACK +# define DYNAMIC_LOADING + /* XXX: see get_end(3), get_etext() and get_end() should not be used. + These aren't used when dyld support is enabled (it is by default) */ +# define DATASTART ((ptr_t) get_etext()) +# define DATAEND ((ptr_t) get_end()) +# define STACKBOTTOM ((ptr_t) 0xc0000000) +# define USE_MMAP +# define USE_MMAP_ANON +# define USE_ASM_PUSH_REGS + /* This is potentially buggy. It needs more testing. See the comments in + os_dep.c. It relies on threads to track writes. */ +# ifdef GC_DARWIN_THREADS +/* # define MPROTECT_VDB -- disabled for now. May work for some apps. */ +# endif +# include +# define GETPAGESIZE() getpagesize() + /* There seems to be some issues with trylock hanging on darwin. This + should be looked into some more */ +# define NO_PTHREAD_TRYLOCK +# endif /* DARWIN */ # endif # ifdef NS32K @@ -1354,8 +1430,8 @@ # define DATAEND /* not needed */ # endif # if defined(NETBSD) -# define OS_TYPE "NETBSD" # define ALIGNMENT 4 +# define OS_TYPE "NETBSD" # define HEURISTIC2 # define USE_GENERIC_PUSH_REGS # ifdef __ELF__ @@ -1387,6 +1463,8 @@ # define CPP_WORDSZ 32 # define STACKBOTTOM ((ptr_t)((ulong)&errno)) # endif +# define USE_MMAP +# define USE_MMAP_ANON /* From AIX linker man page: _text Specifies the first location of the program. _etext Specifies the first location after the program. @@ -1533,7 +1611,7 @@ /* the text segment immediately follows the stack. */ /* Hence we give an upper pound. */ /* This is currently unused, since we disabled HEURISTIC2 */ - extern int __start[]; + extern int __start[]; # define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1))) # ifndef GC_OSF1_THREADS /* Unresolved signal issues with threads. */ @@ -1694,7 +1772,7 @@ # define USE_GENERIC_PUSH_REGS # ifdef UTS4 # define OS_TYPE "UTS4" - extern int etext[]; + extern int etext[]; extern int _etext[]; extern int _end[]; extern ptr_t GC_SysVGetDataStart(); @@ -1708,18 +1786,20 @@ # define MACH_TYPE "S390" # define USE_GENERIC_PUSH_REGS # ifndef __s390x__ -# define ALIGNMENT 4 -# define CPP_WORDSZ 32 +# define ALIGNMENT 4 +# define CPP_WORDSZ 32 # else -# define ALIGNMENT 8 -# define CPP_WORDSZ 64 -# define HBLKSIZE 4096 +# define ALIGNMENT 8 +# define CPP_WORDSZ 64 +# endif +# ifndef HBLKSIZE +# define HBLKSIZE 4096 # endif # ifdef LINUX # define OS_TYPE "LINUX" # define LINUX_STACKBOTTOM # define DYNAMIC_LOADING - extern int __data_start[]; + extern int __data_start[]; # define DATASTART ((ptr_t)(__data_start)) extern int _end[]; # define DATAEND (_end) @@ -1796,6 +1876,19 @@ # endif #endif +# ifdef CRIS +# define MACH_TYPE "CRIS" +# define CPP_WORDSZ 32 +# define ALIGNMENT 1 +# define OS_TYPE "LINUX" +# define DYNAMIC_LOADING +# define LINUX_STACKBOTTOM +# define USE_GENERIC_PUSH_REGS +# define SEARCH_FOR_DATA_START + extern int _end[]; +# define DATAEND (_end) +# endif + # ifdef SH # define MACH_TYPE "SH" # define ALIGNMENT 4 @@ -1812,6 +1905,13 @@ extern int _end[]; # define DATAEND (_end) # endif +# ifdef NETBSD +# define OS_TYPE "NETBSD" +# define HEURISTIC2 +# define DATASTART GC_data_start +# define USE_GENERIC_PUSH_REGS +# define DYNAMIC_LOADING +# endif # endif # ifdef SH4 @@ -2060,8 +2160,9 @@ # define THREADS # endif -# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \ - || defined(LINT) || defined(MSWINCE) || defined(ARM32) \ +# if defined(HP_PA) || defined(M88K) \ + || defined(POWERPC) && !defined(DARWIN) \ + || defined(LINT) || defined(MSWINCE) || defined(ARM32) || defined(CRIS) \ || (defined(I386) && defined(__LCC__)) /* Use setjmp based hack to mark from callee-save registers. */ /* The define should move to the individual platform */ @@ -2202,7 +2303,7 @@ # else # if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC) extern void *GC_amiga_get_mem(size_t size); -# define GET_MEM(bytes) HBLKPTR((size_t) \ +# define GET_MEM(bytes) HBLKPTR((size_t) \ GC_amiga_get_mem((size_t)bytes + GC_page_size) \ + GC_page_size-1) # else @@ -2218,4 +2319,10 @@ #endif /* GC_PRIVATE_H */ +#if defined(_AIX) && !defined(__GNUC__) && !defined(__STDC__) + /* IBMs xlc compiler doesn't appear to follow the convention of */ + /* defining __STDC__ to be zero in extended mode. */ +# define __STDC__ 0 +#endif + # endif /* GCCONFIG_H */ diff -ru gcc-4.0.2.orig/boehm-gc/include/private/pthread_stop_world.h gcc-4.0.2/boehm-gc/include/private/pthread_stop_world.h --- gcc-4.0.2.orig/boehm-gc/include/private/pthread_stop_world.h 2003-07-28 05:46:18.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/private/pthread_stop_world.h 2006-03-10 19:39:28.000000000 +0100 @@ -2,7 +2,6 @@ #define GC_PTHREAD_STOP_WORLD_H struct thread_stop_info { - int signal; word last_stop_count; /* GC_last_stop_count value when thread */ /* last successfully handled a suspend */ /* signal. */ diff -ru gcc-4.0.2.orig/boehm-gc/include/private/pthread_support.h gcc-4.0.2/boehm-gc/include/private/pthread_support.h --- gcc-4.0.2.orig/boehm-gc/include/private/pthread_support.h 2004-08-14 01:05:35.000000000 +0200 +++ gcc-4.0.2/boehm-gc/include/private/pthread_support.h 2006-03-10 19:39:28.000000000 +0100 @@ -4,7 +4,7 @@ # include "private/gc_priv.h" # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) + && !defined(GC_WIN32_THREADS) #if defined(GC_DARWIN_THREADS) # include "private/darwin_stop_world.h" diff -ru gcc-4.0.2.orig/boehm-gc/mach_dep.c gcc-4.0.2/boehm-gc/mach_dep.c --- gcc-4.0.2.orig/boehm-gc/mach_dep.c 2005-02-09 22:33:02.000000000 +0100 +++ gcc-4.0.2/boehm-gc/mach_dep.c 2006-03-10 19:39:29.000000000 +0100 @@ -27,6 +27,10 @@ # endif # endif +#if defined(RS6000) || defined(POWERPC) +# include +#endif + #if defined(__MWERKS__) && !defined(POWERPC) asm static void PushMacRegisters() @@ -413,6 +417,13 @@ /* the stack. */ __builtin_unwind_init(); # else /* !HAVE_BUILTIN_UNWIND_INIT */ +# if defined(RS6000) || defined(POWERPC) + /* FIXME: RS6000 means AIX. */ + /* This should probably be used in all Posix/non-gcc */ + /* settings. We defer that change to minimize risk. */ + ucontext_t ctxt; + getcontext(&ctxt); +# else /* Generic code */ /* The idea is due to Parag Patel at HP. */ /* We're not sure whether he would like */ @@ -426,7 +437,7 @@ for (; (char *)i < lim; i++) { *i = 0; } -# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ +# if defined(MSWIN32) || defined(MSWINCE) \ || defined(UTS4) || defined(LINUX) || defined(EWS4800) (void) setjmp(regs); # else @@ -435,15 +446,16 @@ /* SUSV3, setjmp() may or may not save signal mask. */ /* _setjmp won't, but is less portable. */ # endif +# endif /* !AIX ... */ # endif /* !HAVE_BUILTIN_UNWIND_INIT */ -# elif defined(PTHREADS) && !defined(MSWIN32) /* !USE_GENERIC_PUSH_REGS */ - /* We may still need this to save thread contexts. */ - /* This should probably be used in all Posix/non-gcc */ - /* settings. We defer that change to minimize risk. */ - ucontext_t ctxt; - getcontext(&ctxt); -# else /* Shouldn't be needed */ - ABORT("Unexpected call to GC_with_callee_saves_pushed"); +# else +# if defined(PTHREADS) && !defined(MSWIN32) /* !USE_GENERIC_PUSH_REGS */ + /* We may still need this to save thread contexts. */ + ucontext_t ctxt; + getcontext(&ctxt); +# else /* Shouldn't be needed */ + ABORT("Unexpected call to GC_with_callee_saves_pushed"); +# endif # endif # if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ || defined(IA64) @@ -480,7 +492,7 @@ /* the stack. Return sp. */ # ifdef SPARC asm(" .seg \"text\""); -# if defined(SVR4) || defined(NETBSD) +# if defined(SVR4) || defined(NETBSD) || defined(FREEBSD) asm(" .globl GC_save_regs_in_stack"); asm("GC_save_regs_in_stack:"); asm(" .type GC_save_regs_in_stack,#function"); diff -ru gcc-4.0.2.orig/boehm-gc/mallocx.c gcc-4.0.2/boehm-gc/mallocx.c --- gcc-4.0.2.orig/boehm-gc/mallocx.c 2004-08-14 01:05:30.000000000 +0200 +++ gcc-4.0.2/boehm-gc/mallocx.c 2006-03-10 19:39:29.000000000 +0100 @@ -172,7 +172,8 @@ # endif /* REDIRECT_REALLOC */ -/* The same thing, except caller does not hold allocation lock. */ +/* Allocate memory such that only pointers to near the */ +/* beginning of the object are considered. */ /* We avoid holding allocation lock while we clear memory. */ ptr_t GC_generic_malloc_ignore_off_page(lb, k) register size_t lb; diff -ru gcc-4.0.2.orig/boehm-gc/mark.c gcc-4.0.2/boehm-gc/mark.c --- gcc-4.0.2.orig/boehm-gc/mark.c 2004-08-14 01:05:30.000000000 +0200 +++ gcc-4.0.2/boehm-gc/mark.c 2006-03-10 19:39:29.000000000 +0100 @@ -858,9 +858,9 @@ ++top; top -> mse_descr = descr; top -> mse_start = p -> mse_start; - GC_ASSERT( top -> mse_descr & GC_DS_TAGS != GC_DS_LENGTH || - top -> mse_descr < GC_greatest_plausible_heap_addr - - GC_least_plausible_heap_addr); + GC_ASSERT( (top -> mse_descr & GC_DS_TAGS) != GC_DS_LENGTH || + top -> mse_descr < (ptr_t)GC_greatest_plausible_heap_addr + - (ptr_t)GC_least_plausible_heap_addr); /* If this is a big object, count it as */ /* size/256 + 1 objects. */ ++i; @@ -1450,8 +1450,8 @@ ptr_t bottom; ptr_t top; { - word * b = (word *)(((long) bottom + ALIGNMENT-1) & ~(ALIGNMENT-1)); - word * t = (word *)(((long) top) & ~(ALIGNMENT-1)); + word * b = (word *)(((word) bottom + ALIGNMENT-1) & ~(ALIGNMENT-1)); + word * t = (word *)(((word) top) & ~(ALIGNMENT-1)); register word *p; register word q; register word *lim; diff -ru gcc-4.0.2.orig/boehm-gc/misc.c gcc-4.0.2/boehm-gc/misc.c --- gcc-4.0.2.orig/boehm-gc/misc.c 2004-08-21 09:49:17.000000000 +0200 +++ gcc-4.0.2/boehm-gc/misc.c 2006-03-10 19:39:29.000000000 +0100 @@ -246,7 +246,7 @@ byte_sz = WORDS_TO_BYTES(word_sz); if (GC_all_interior_pointers) { /* We need one extra byte; don't fill in GC_size_map[byte_sz] */ - byte_sz--; + byte_sz -= EXTRA_BYTES; } for (j = low_limit; j <= byte_sz; j++) GC_size_map[j] = word_sz; @@ -805,7 +805,10 @@ void GC_enable_incremental GC_PROTO(()) { -# if !defined(SMALL_CONFIG) +# if !defined(SMALL_CONFIG) && !defined(KEEP_BACK_PTRS) + /* If we are keeping back pointers, the GC itself dirties all */ + /* pages on which objects have been marked, making */ + /* incremental GC pointless. */ if (!GC_find_leak) { DCL_LOCK_STATE; diff -ru gcc-4.0.2.orig/boehm-gc/os_dep.c gcc-4.0.2/boehm-gc/os_dep.c --- gcc-4.0.2.orig/boehm-gc/os_dep.c 2005-04-22 20:11:30.000000000 +0200 +++ gcc-4.0.2/boehm-gc/os_dep.c 2006-03-10 19:39:29.000000000 +0100 @@ -60,6 +60,10 @@ # include # endif +#if defined(LINUX) || defined(LINUX_STACKBOTTOM) +# include +#endif + /* Blatantly OS dependent routines, except for those that are related */ /* to dynamic loading. */ @@ -80,7 +84,7 @@ # define NEED_FIND_LIMIT # endif -#if defined(FREEBSD) && defined(I386) +#if defined(FREEBSD) && (defined(I386) || defined(powerpc) || defined(__powerpc__)) # include # if !defined(PCR) # define NEED_FIND_LIMIT @@ -245,30 +249,11 @@ // XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537 name of mapping...\n // ^^^^^^^^ ^^^^^^^^ ^^^^ ^^ // start end prot maj_dev -// 0 9 18 32 -// -// For 64 bit ABIs: -// 0 17 34 56 // -// The parser is called with a pointer to the entry and the return value -// is either NULL or is advanced to the next entry(the byte after the -// trailing '\n'.) +// Note that since about auguat 2003 kernels, the columns no longer have +// fixed offsets on 64-bit kernels. Hence we no longer rely on fixed offsets +// anywhere, which is safer anyway. // -#if CPP_WORDSZ == 32 -# define OFFSET_MAP_START 0 -# define OFFSET_MAP_END 9 -# define OFFSET_MAP_PROT 18 -# define OFFSET_MAP_MAJDEV 32 -# define ADDR_WIDTH 8 -#endif - -#if CPP_WORDSZ == 64 -# define OFFSET_MAP_START 0 -# define OFFSET_MAP_END 17 -# define OFFSET_MAP_PROT 34 -# define OFFSET_MAP_MAJDEV 56 -# define ADDR_WIDTH 16 -#endif /* * Assign various fields of the first line in buf_ptr to *start, *end, @@ -277,37 +262,46 @@ char *GC_parse_map_entry(char *buf_ptr, word *start, word *end, char *prot_buf, unsigned int *maj_dev) { - int i; - char *tok; + char *start_start, *end_start, *prot_start, *maj_dev_start; + char *p; + char *endp; if (buf_ptr == NULL || *buf_ptr == '\0') { return NULL; } - memcpy(prot_buf, buf_ptr+OFFSET_MAP_PROT, 4); - /* do the protections first. */ + p = buf_ptr; + while (isspace(*p)) ++p; + start_start = p; + GC_ASSERT(isxdigit(*start_start)); + *start = strtoul(start_start, &endp, 16); p = endp; + GC_ASSERT(*p=='-'); + + ++p; + end_start = p; + GC_ASSERT(isxdigit(*end_start)); + *end = strtoul(end_start, &endp, 16); p = endp; + GC_ASSERT(isspace(*p)); + + while (isspace(*p)) ++p; + prot_start = p; + GC_ASSERT(*prot_start == 'r' || *prot_start == '-'); + memcpy(prot_buf, prot_start, 4); prot_buf[4] = '\0'; - - if (prot_buf[1] == 'w') {/* we can skip all of this if it's not writable. */ - - tok = buf_ptr; - buf_ptr[OFFSET_MAP_START+ADDR_WIDTH] = '\0'; - *start = strtoul(tok, NULL, 16); - - tok = buf_ptr+OFFSET_MAP_END; - buf_ptr[OFFSET_MAP_END+ADDR_WIDTH] = '\0'; - *end = strtoul(tok, NULL, 16); - - buf_ptr += OFFSET_MAP_MAJDEV; - tok = buf_ptr; - while (*buf_ptr != ':') buf_ptr++; - *buf_ptr++ = '\0'; - *maj_dev = strtoul(tok, NULL, 16); + if (prot_buf[1] == 'w') {/* we can skip the rest if it's not writable. */ + /* Skip past protection field to offset field */ + while (!isspace(*p)) ++p; while (isspace(*p)) ++p; + GC_ASSERT(isxdigit(*p)); + /* Skip past offset field, which we ignore */ + while (!isspace(*p)) ++p; while (isspace(*p)) ++p; + maj_dev_start = p; + GC_ASSERT(isxdigit(*maj_dev_start)); + *maj_dev = strtoul(maj_dev_start, NULL, 16); } - while (*buf_ptr && *buf_ptr++ != '\n'); + while (*p && *p++ != '\n'); - return buf_ptr; + return p; } #endif /* Need to parse /proc/self/maps. */ @@ -699,7 +693,7 @@ # if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \ || defined(HURD) || defined(NETBSD) static struct sigaction old_segv_act; -# if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) \ +# if defined(IRIX5) || defined(HPUX) \ || defined(HURD) || defined(NETBSD) static struct sigaction old_bus_act; # endif @@ -732,9 +726,11 @@ /* and setting a handler at the same time. */ (void) sigaction(SIGSEGV, 0, &old_segv_act); (void) sigaction(SIGSEGV, &act, 0); + (void) sigaction(SIGBUS, 0, &old_bus_act); + (void) sigaction(SIGBUS, &act, 0); # else (void) sigaction(SIGSEGV, &act, &old_segv_act); -# if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ +# if defined(IRIX5) \ || defined(HPUX) || defined(HURD) || defined(NETBSD) /* Under Irix 5.x or HP/UX, we may get SIGBUS. */ /* Pthreads doesn't exist under Irix 5.x, so we */ @@ -773,7 +769,7 @@ # if defined(SUNOS5SIGS) || defined(IRIX5) \ || defined(OSF1) || defined(HURD) || defined(NETBSD) (void) sigaction(SIGSEGV, &old_segv_act, 0); -# if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ +# if defined(IRIX5) \ || defined(HPUX) || defined(HURD) || defined(NETBSD) (void) sigaction(SIGBUS, &old_bus_act, 0); # endif @@ -854,13 +850,14 @@ #include #include -#include # define STAT_SKIP 27 /* Number of fields preceding startstack */ /* field in /proc/self/stat */ +#ifdef USE_LIBC_PRIVATES # pragma weak __libc_stack_end extern ptr_t __libc_stack_end; +#endif # ifdef IA64 /* Try to read the backing store base from /proc/self/maps. */ @@ -890,30 +887,33 @@ return GC_apply_to_maps(backing_store_base_from_maps); } -# pragma weak __libc_ia64_register_backing_store_base - extern ptr_t __libc_ia64_register_backing_store_base; +# ifdef USE_LIBC_PRIVATES +# pragma weak __libc_ia64_register_backing_store_base + extern ptr_t __libc_ia64_register_backing_store_base; +# endif ptr_t GC_get_register_stack_base(void) { - if (0 != &__libc_ia64_register_backing_store_base - && 0 != __libc_ia64_register_backing_store_base) { - /* Glibc 2.2.4 has a bug such that for dynamically linked */ - /* executables __libc_ia64_register_backing_store_base is */ - /* defined but uninitialized during constructor calls. */ - /* Hence we check for both nonzero address and value. */ - return __libc_ia64_register_backing_store_base; - } else { - word result = backing_store_base_from_proc(); - if (0 == result) { +# ifdef USE_LIBC_PRIVATES + if (0 != &__libc_ia64_register_backing_store_base + && 0 != __libc_ia64_register_backing_store_base) { + /* Glibc 2.2.4 has a bug such that for dynamically linked */ + /* executables __libc_ia64_register_backing_store_base is */ + /* defined but uninitialized during constructor calls. */ + /* Hence we check for both nonzero address and value. */ + return __libc_ia64_register_backing_store_base; + } +# endif + word result = backing_store_base_from_proc(); + if (0 == result) { /* Use dumb heuristics. Works only for default configuration. */ result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT; result += BACKING_STORE_ALIGNMENT - 1; result &= ~(BACKING_STORE_ALIGNMENT - 1); /* Verify that it's at least readable. If not, we goofed. */ GC_noop1(*(word *)result); - } - return (ptr_t)result; } + return (ptr_t)result; } # endif @@ -936,6 +936,7 @@ /* since the correct value of __libc_stack_end never */ /* becomes visible to us. The second test works around */ /* this. */ +# ifdef USE_LIBC_PRIVATES if (0 != &__libc_stack_end && 0 != __libc_stack_end ) { # ifdef IA64 /* Some versions of glibc set the address 16 bytes too */ @@ -957,6 +958,7 @@ # endif # endif } +# endif f = open("/proc/self/stat", O_RDONLY); if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) { ABORT("Couldn't read /proc/self/stat"); @@ -1387,7 +1389,7 @@ } # endif -# if defined(FREEBSD) && defined(I386) && !defined(PCR) +# if defined(FREEBSD) && (defined(I386) || defined(powerpc) || defined(__powerpc__)) && !defined(PCR) /* Its unclear whether this should be identical to the above, or */ /* whether it should apply to non-X86 architectures. */ /* For now we don't assume that there is always an empty page after */ @@ -1508,7 +1510,7 @@ # endif -# ifdef RS6000 +# if 0 && defined(RS6000) /* We now use mmap */ /* The compiler seems to generate speculative reads one past the end of */ /* an allocated object. Hence we need to make sure that the page */ /* following the last heap page is also mapped. */ @@ -2381,7 +2383,7 @@ # endif # ifdef FREEBSD # define SIG_OK (sig == SIGBUS) -# define CODE_OK (code == BUS_PAGE_FAULT) +# define CODE_OK TRUE # endif # endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */ @@ -2519,7 +2521,11 @@ # if defined(ARM32) char * addr = (char *)sc.fault_address; # else - --> architecture not supported +# if defined(CRIS) + char * addr = (char *)sc.regs.csraddr; +# else + --> architecture not supported +# endif # endif # endif # endif @@ -3722,7 +3728,7 @@ exception_behavior_t behavior; thread_state_flavor_t flavor; - thread_state_data_t thread_state; + thread_state_t thread_state; mach_msg_type_number_t thread_state_count = THREAD_STATE_MAX; for(i=0;i # else -# if defined(OPENBSD) || defined(NETBSD) +# if defined(OPENBSD) # include # else -# include +# if defined(FREEBSD) || defined(NETBSD) +# include +# else +# include +# endif # endif # endif # endif @@ -3981,6 +4007,16 @@ #if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \ && defined(GC_HAVE_BUILTIN_BACKTRACE) +#ifdef REDIRECT_MALLOC + /* Deal with possible malloc calls in backtrace by omitting */ + /* the infinitely recursing backtrace. */ +# ifdef THREADS + __thread /* If your compiler doesn't understand this */ + /* you could use something like pthread_getspecific. */ +# endif + GC_in_save_callers = FALSE; +#endif + void GC_save_callers (info) struct callinfo info[NFRAMES]; { @@ -3990,15 +4026,26 @@ /* We retrieve NFRAMES+1 pc values, but discard the first, since it */ /* points to our own frame. */ +# ifdef REDIRECT_MALLOC + if (GC_in_save_callers) { + info[0].ci_pc = (word)(&GC_save_callers); + for (i = 1; i < NFRAMES; ++i) info[i].ci_pc = 0; + return; + } + GC_in_save_callers = TRUE; +# endif 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; +# ifdef REDIRECT_MALLOC + GC_in_save_callers = FALSE; +# endif } #else /* No builtin backtrace; do it ourselves */ -#if (defined(OPENBSD) || defined(NETBSD)) && defined(SPARC) +#if (defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD)) && defined(SPARC) # define FR_SAVFP fr_fp # define FR_SAVPC fr_pc #else diff -ru gcc-4.0.2.orig/boehm-gc/powerpc_darwin_mach_dep.s gcc-4.0.2/boehm-gc/powerpc_darwin_mach_dep.s --- gcc-4.0.2.orig/boehm-gc/powerpc_darwin_mach_dep.s 2004-08-15 23:32:11.000000000 +0200 +++ gcc-4.0.2/boehm-gc/powerpc_darwin_mach_dep.s 2006-03-10 19:39:29.000000000 +0100 @@ -1,10 +1,21 @@ +#if defined(__ppc64__) +#define MODE_CHOICE(x, y) y +#else +#define MODE_CHOICE(x, y) x +#endif + +#define lgu MODE_CHOICE(lwzu, ldu) + +#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ + +#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ ; GC_push_regs function. Under some optimization levels GCC will clobber ; some of the non-volatile registers before we get a chance to save them -; therefore, this can't be inline asm. +; therefore, this cannot be inline asm. .text - .align 2 + .align LOG2_GPR_BYTES .globl _GC_push_regs _GC_push_regs: @@ -65,7 +76,7 @@ .data .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align 2 + .align LOG2_GPR_BYTES L_GC_push_one$stub: .indirect_symbol _GC_push_one mflr r0 @@ -74,11 +85,11 @@ mflr r11 addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one) mtlr r0 - lwzu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11) + lgu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11) mtctr r12 bctr .data .lazy_symbol_pointer L_GC_push_one$lazy_ptr: .indirect_symbol _GC_push_one - .long dyld_stub_binding_helper + .g_long dyld_stub_binding_helper diff -ru gcc-4.0.2.orig/boehm-gc/pthread_stop_world.c gcc-4.0.2/boehm-gc/pthread_stop_world.c --- gcc-4.0.2.orig/boehm-gc/pthread_stop_world.c 2005-02-09 22:33:02.000000000 +0100 +++ gcc-4.0.2/boehm-gc/pthread_stop_world.c 2006-03-10 19:39:29.000000000 +0100 @@ -1,13 +1,17 @@ #include "private/pthread_support.h" #if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \ - && !defined(GC_DARWIN_THREADS) && !defined(GC_AIX_THREADS) + && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS) #include #include #include #include +#include +#ifndef HPUX +# include + /* Doesn't exist on HP/UX 11.11. */ +#endif #if DEBUG_THREADS @@ -67,7 +71,22 @@ static sigset_t suspend_handler_mask; -word GC_stop_count; /* Incremented at the beginning of GC_stop_world. */ +volatile sig_atomic_t GC_stop_count; + /* Incremented at the beginning of GC_stop_world. */ + +volatile sig_atomic_t GC_world_is_stopped = FALSE; + /* FALSE ==> it is safe for threads to restart, i.e. */ + /* they will see another suspend signal before they */ + /* are expected to stop (unless they have voluntarily */ + /* stopped). */ + +void GC_brief_async_signal_safe_sleep() +{ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000 * TIME_LIMIT / 2; + select(0, 0, 0, 0, &tv); +} #ifdef GC_OSF1_THREADS GC_bool GC_retry_signals = TRUE; @@ -108,7 +127,9 @@ void GC_suspend_handler(int sig) { + int old_errno = errno; GC_with_callee_saves_pushed(GC_suspend_handler_inner, (ptr_t)(word)sig); + errno = old_errno; } #else @@ -116,7 +137,9 @@ /* in the signal handler frame. */ void GC_suspend_handler(int sig) { + int old_errno = errno; GC_suspend_handler_inner((ptr_t)(word)sig); + errno = old_errno; } #endif @@ -172,16 +195,26 @@ /* this thread a SIG_THR_RESTART signal. */ /* SIG_THR_RESTART should be masked at this point. Thus there */ /* is no race. */ - do { - me->stop_info.signal = 0; - sigsuspend(&suspend_handler_mask); /* Wait for signal */ - } while (me->stop_info.signal != SIG_THR_RESTART); + /* We do not continue until we receive a SIG_THR_RESTART, */ + /* but we do not take that as authoritative. (We may be */ + /* accidentally restarted by one of the user signals we */ + /* don't block.) After we receive the signal, we use a */ + /* primitive and expensive mechanism to wait until it's */ + /* really safe to proceed. Under normal circumstances, */ + /* this code should not be executed. */ + sigsuspend(&suspend_handler_mask); /* Wait for signal */ + while (GC_world_is_stopped && GC_stop_count == my_stop_count) { + GC_brief_async_signal_safe_sleep(); +# if DEBUG_THREADS + GC_err_printf0("Sleeping in signal handler"); +# endif + } /* If the RESTART signal gets lost, we can still lose. That should be */ /* less likely than losing the SUSPEND signal, since we don't do much */ /* between the sem_post and sigsuspend. */ - /* We'd need more handshaking to work around that, since we don't want */ - /* to accidentally leave a RESTART signal pending, thus causing us to */ - /* continue prematurely in a future round. */ + /* We'd need more handshaking to work around that. */ + /* Simply dropping the sigsuspend call should be safe, but is unlikely */ + /* to be efficient. */ #if DEBUG_THREADS GC_printf1("Continuing 0x%lx\n", my_thread); @@ -191,20 +224,11 @@ void GC_restart_handler(int sig) { pthread_t my_thread = pthread_self(); - GC_thread me; if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler"); - /* Let the GC_suspend_handler() know that we got a SIG_THR_RESTART. */ - /* The lookup here is safe, since I'm doing this on behalf */ - /* of a thread which holds the allocation lock in order */ - /* to stop the world. Thus concurrent modification of the */ - /* data structure is impossible. */ - me = GC_lookup_thread(my_thread); - me->stop_info.signal = SIG_THR_RESTART; - /* - ** Note: even if we didn't do anything useful here, + ** Note: even if we don't do anything useful here, ** it would still be necessary to have a signal handler, ** rather than ignoring the signals, otherwise ** the signals will not be delivered at all, and @@ -357,6 +381,7 @@ /* We should have previously waited for it to become zero. */ # endif /* PARALLEL_MARK */ ++GC_stop_count; + GC_world_is_stopped = TRUE; n_live_threads = GC_suspend_all(); if (GC_retry_signals) { @@ -390,10 +415,10 @@ } for (i = 0; i < n_live_threads; i++) { while (0 != (code = sem_wait(&GC_suspend_ack_sem))) { - if (errno != EINTR) { - GC_err_printf1("Sem_wait returned %ld\n", (unsigned long)code); - ABORT("sem_wait for handler failed"); - } + if (errno != EINTR) { + GC_err_printf1("Sem_wait returned %ld\n", (unsigned long)code); + ABORT("sem_wait for handler failed"); + } } } # ifdef PARALLEL_MARK @@ -419,6 +444,7 @@ GC_printf0("World starting\n"); # endif + GC_world_is_stopped = FALSE; for (i = 0; i < THREAD_TABLE_SZ; i++) { for (p = GC_threads[i]; p != 0; p = p -> next) { if (p -> id != my_thread) { @@ -428,8 +454,7 @@ #if DEBUG_THREADS GC_printf1("Sending restart signal to 0x%lx\n", p -> id); #endif - - result = pthread_kill(p -> id, SIG_THR_RESTART); + result = pthread_kill(p -> id, SIG_THR_RESTART); switch(result) { case ESRCH: /* Not really there anymore. Possible? */ diff -ru gcc-4.0.2.orig/boehm-gc/pthread_support.c gcc-4.0.2/boehm-gc/pthread_support.c --- gcc-4.0.2.orig/boehm-gc/pthread_support.c 2004-08-14 01:05:30.000000000 +0200 +++ gcc-4.0.2/boehm-gc/pthread_support.c 2006-03-10 19:39:29.000000000 +0100 @@ -2,7 +2,7 @@ * Copyright (c) 1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 1998 by Fergus Henderson. All rights reserved. - * Copyright (c) 2000-2001 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 2000-2004 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. @@ -47,12 +47,18 @@ /*#define DEBUG_THREADS 1*/ /*#define GC_ASSERTIONS*/ +#include "gc_config.h" + +#ifdef GC_PTHREAD_SYM_VERSION +#define _GNU_SOURCE +#include +#endif + # include "gc.h" # include "private/pthread_support.h" # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \ - && !defined(GC_AIX_THREADS) + && !defined(GC_WIN32_THREADS) # if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \ && !defined(USE_COMPILER_TLS) @@ -69,7 +75,8 @@ # endif # if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \ - defined(GC_DARWIN_THREADS)) && !defined(USE_PTHREAD_SPECIFIC) + defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) \ + && !defined(USE_PTHREAD_SPECIFIC) # define USE_PTHREAD_SPECIFIC # endif @@ -117,7 +124,7 @@ # include #endif /* !GC_DARWIN_THREADS */ -#if defined(GC_DARWIN_THREADS) +#if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) # include #endif /* GC_DARWIN_THREADS */ @@ -840,9 +847,9 @@ /* We hold the allocation lock. */ void GC_thr_init() { -# ifndef GC_DARWIN_THREADS - int dummy; -# endif +# ifndef GC_DARWIN_THREADS + int dummy; +# endif GC_thread t; if (GC_thr_initialized) return; @@ -874,14 +881,15 @@ # if defined(GC_HPUX_THREADS) GC_nprocs = pthread_num_processors_np(); # endif -# if defined(GC_OSF1_THREADS) +# if defined(GC_OSF1_THREADS) || defined(GC_AIX_THREADS) GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN); if (GC_nprocs <= 0) GC_nprocs = 1; # endif -# if defined(GC_FREEBSD_THREADS) - GC_nprocs = 1; +# if defined(GC_IRIX_THREADS) + GC_nprocs = sysconf(_SC_NPROC_ONLN); + if (GC_nprocs <= 0) GC_nprocs = 1; # endif -# if defined(GC_DARWIN_THREADS) +# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) int ncpus = 1; size_t len = sizeof(ncpus); sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0); @@ -928,6 +936,8 @@ /* Disable true incremental collection, but generational is OK. */ GC_time_limit = GC_TIME_UNLIMITED; } + /* If we are using a parallel marker, actually start helper threads. */ + if (GC_parallel) start_mark_threads(); # endif } @@ -944,10 +954,6 @@ /* GC_init() calls us back, so set flag first. */ if (!GC_is_initialized) GC_init(); - /* If we are using a parallel marker, start the helper threads. */ -# ifdef PARALLEL_MARK - if (GC_parallel) start_mark_threads(); -# endif /* Initialize thread local free lists if used. */ # if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL) LOCK(); @@ -1194,8 +1200,37 @@ return(result); } +#ifdef GC_PTHREAD_SYM_VERSION + +/* Force constr to execute prior to main(). */ +static void constr (void) __attribute__ ((constructor)); + +static int +(*pthread_create_)(pthread_t *new_thread, + const pthread_attr_t *attr_in, + void * (*thread_execp)(void *), void *arg); + +static void +constr (void) +{ + /* Get a pointer to the real pthread_create. */ + pthread_create_ = dlvsym (RTLD_NEXT, "pthread_create", + GC_PTHREAD_SYM_VERSION); +} + +#define GC_PTHREAD_CREATE_NAME pthread_create +#define GC_PTHREAD_REAL_NAME (*pthread_create_) + +#else + +#define GC_PTHREAD_CREATE_NAME WRAP_FUNC(pthread_create) +#define GC_PTHREAD_REAL_NAME REAL_FUNC(pthread_create) + +#endif + + int -WRAP_FUNC(pthread_create)(pthread_t *new_thread, +GC_PTHREAD_CREATE_NAME(pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { @@ -1223,7 +1258,7 @@ if (!GC_thr_initialized) GC_thr_init(); # ifdef GC_ASSERTIONS { - int stack_size; + size_t stack_size; if (NULL == attr) { pthread_attr_t my_attr; pthread_attr_init(&my_attr); @@ -1231,7 +1266,13 @@ } else { pthread_attr_getstacksize(attr, &stack_size); } - GC_ASSERT(stack_size >= (8*HBLKSIZE*sizeof(word))); +# ifdef PARALLEL_MARK + GC_ASSERT(stack_size >= (8*HBLKSIZE*sizeof(word))); +# else + /* FreeBSD-5.3/Alpha: default pthread stack is 64K, */ + /* HBLKSIZE=8192, sizeof(word)=8 */ + GC_ASSERT(stack_size >= 65536); +# endif /* Our threads may need to do some work for the GC. */ /* Ridiculously small threads won't work, and they */ /* probably wouldn't work anyway. */ @@ -1250,7 +1291,7 @@ pthread_self()); # endif - result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, si); + result = GC_PTHREAD_REAL_NAME(new_thread, attr, GC_start_routine, si); # ifdef DEBUG_THREADS GC_printf1("Started thread 0x%X\n", *new_thread); diff -ru gcc-4.0.2.orig/boehm-gc/reclaim.c gcc-4.0.2/boehm-gc/reclaim.c --- gcc-4.0.2.orig/boehm-gc/reclaim.c 2003-07-28 06:18:20.000000000 +0200 +++ gcc-4.0.2/boehm-gc/reclaim.c 2006-03-10 19:39:29.000000000 +0100 @@ -888,7 +888,7 @@ { struct Print_stats pstats; - GC_printf0("(kind(0=ptrfree,1=normal,2=unc.,3=stubborn):size_in_bytes, #_marks_set)\n"); + GC_printf1("(kind(0=ptrfree,1=normal,2=unc.,%lu=stubborn):size_in_bytes, #_marks_set)\n", STUBBORN); pstats.number_of_blocks = 0; pstats.total_bytes = 0; GC_apply_to_all_blocks(GC_print_block_descr, (word)&pstats); diff -ru gcc-4.0.2.orig/boehm-gc/solaris_pthreads.c gcc-4.0.2/boehm-gc/solaris_pthreads.c --- gcc-4.0.2.orig/boehm-gc/solaris_pthreads.c 2004-08-16 18:32:26.000000000 +0200 +++ gcc-4.0.2/boehm-gc/solaris_pthreads.c 2006-03-10 19:39:29.000000000 +0100 @@ -16,7 +16,7 @@ * Modified by Peter C. for Solaris Posix Threads. */ -#include "private/gc_priv.h" +# include "private/gc_priv.h" # if defined(GC_SOLARIS_PTHREADS) # include diff -ru gcc-4.0.2.orig/boehm-gc/solaris_threads.c gcc-4.0.2/boehm-gc/solaris_threads.c --- gcc-4.0.2.orig/boehm-gc/solaris_threads.c 2004-08-16 18:32:26.000000000 +0200 +++ gcc-4.0.2/boehm-gc/solaris_threads.c 2006-03-10 19:39:29.000000000 +0100 @@ -16,7 +16,7 @@ */ /* Boehm, September 14, 1994 4:44 pm PDT */ -#include "private/gc_priv.h" +# include "private/gc_priv.h" # if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS) # include "private/solaris_threads.h" @@ -248,8 +248,8 @@ for (i = 0; i < max_lwps; i++) last_ids[i] = 0; for (;;) { - if (syscall(SYS_ioctl, GC_main_proc_fd, PIOCSTATUS, &status) < 0) - ABORT("Main PIOCSTATUS failed"); + if (syscall(SYS_ioctl, GC_main_proc_fd, PIOCSTATUS, &status) < 0) + ABORT("Main PIOCSTATUS failed"); if (status.pr_nlwp < 1) ABORT("Invalid number of lwps returned by PIOCSTATUS"); if (status.pr_nlwp >= max_lwps) { @@ -262,7 +262,7 @@ for (i = 0; i < max_lwps; i++) last_ids[i] = 0; continue; - } + } if (syscall(SYS_ioctl, GC_main_proc_fd, PIOCLWPIDS, GC_current_ids) < 0) ABORT("PIOCLWPIDS failed"); changed = FALSE; diff -ru gcc-4.0.2.orig/boehm-gc/tests/test.c gcc-4.0.2/boehm-gc/tests/test.c --- gcc-4.0.2.orig/boehm-gc/tests/test.c 2004-08-14 01:05:35.000000000 +0200 +++ gcc-4.0.2/boehm-gc/tests/test.c 2006-03-10 19:39:27.000000000 +0100 @@ -1367,6 +1367,10 @@ max_heap_sz = 11000000; } # endif +# ifndef ALIGN_DOUBLE + /* We end up needing more small object pages. */ + max_heap_sz += 2000000; +# endif # ifdef GC_DEBUG max_heap_sz *= 2; # ifdef SAVE_CALL_CHAIN diff -ru gcc-4.0.2.orig/boehm-gc/threadlibs.c gcc-4.0.2/boehm-gc/threadlibs.c --- gcc-4.0.2.orig/boehm-gc/threadlibs.c 2004-08-14 01:05:30.000000000 +0200 +++ gcc-4.0.2/boehm-gc/threadlibs.c 2006-03-10 19:39:29.000000000 +0100 @@ -11,10 +11,17 @@ "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n"); # endif # if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \ - || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) \ + || defined(GC_SOLARIS_PTHREADS) \ || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) printf("-lpthread\n"); # endif +# if defined(GC_FREEBSD_THREADS) +# if (__FREEBSD_version >= 500000) + printf("-lpthread\n"); +# else + printf("-pthread\n"); +# endif +# endif # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) printf("-lpthread -lrt\n"); # endif diff -ru gcc-4.0.2.orig/boehm-gc/version.h gcc-4.0.2/boehm-gc/version.h --- gcc-4.0.2.orig/boehm-gc/version.h 2004-08-14 01:05:30.000000000 +0200 +++ gcc-4.0.2/boehm-gc/version.h 2006-03-10 19:39:29.000000000 +0100 @@ -2,7 +2,7 @@ /* Eventually this one may become unnecessary. For now we need */ /* it to keep the old-style build process working. */ #define GC_TMP_VERSION_MAJOR 6 -#define GC_TMP_VERSION_MINOR 3 +#define GC_TMP_VERSION_MINOR 6 #define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA #ifndef GC_NOT_ALPHA diff -ru gcc-4.0.2.orig/boehm-gc/win32_threads.c gcc-4.0.2/boehm-gc/win32_threads.c --- gcc-4.0.2.orig/boehm-gc/win32_threads.c 2004-08-23 17:07:00.000000000 +0200 +++ gcc-4.0.2/boehm-gc/win32_threads.c 2006-03-10 19:39:29.000000000 +0100 @@ -11,6 +11,7 @@ # undef pthread_create # undef pthread_sigmask # undef pthread_join +# undef pthread_detach # undef dlopen # define DEBUG_CYGWIN_THREADS 0 @@ -185,7 +186,7 @@ /* Must still be in_use, since nobody else can store our thread_id. */ i++) {} if (i > my_max) { - WARN("Removing nonexisiting thread %ld\n", (GC_word)thread_id); + WARN("Removing nonexistent thread %ld\n", (GC_word)thread_id); } else { GC_delete_gc_thread(thread_table+i); } @@ -232,6 +233,9 @@ # endif } +/* Defined in misc.c */ +extern CRITICAL_SECTION GC_write_cs; + void GC_stop_world() { DWORD thread_id = GetCurrentThreadId(); @@ -240,6 +244,9 @@ if (!GC_thr_initialized) ABORT("GC_stop_world() called before GC_thr_init()"); GC_please_stop = TRUE; +# ifndef CYGWIN32 + EnterCriticalSection(&GC_write_cs); +# endif /* !CYGWIN32 */ for (i = 0; i <= GC_get_max_thread_index(); i++) if (thread_table[i].stack_base != 0 && thread_table[i].id != thread_id) { @@ -270,6 +277,9 @@ # endif thread_table[i].suspended = TRUE; } +# ifndef CYGWIN32 + LeaveCriticalSection(&GC_write_cs); +# endif /* !CYGWIN32 */ } void GC_start_world() diff -ru gcc-4.0.2.orig/configure gcc-4.0.2/configure --- gcc-4.0.2.orig/configure 2005-09-13 09:01:28.000000000 +0200 +++ gcc-4.0.2/configure 2006-03-10 19:37:04.000000000 +0100 @@ -1159,12 +1159,8 @@ *-*-chorusos) noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}" ;; - powerpc-*-darwin*) - noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes gdb gprof" - ;; *-*-darwin*) noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes gdb gprof" - noconfigdirs="$noconfigdirs ${libgcj}" ;; *-*-freebsd[12] | *-*-freebsd[12].* | *-*-freebsd*aout*) noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}" diff -ru gcc-4.0.2.orig/configure.in gcc-4.0.2/configure.in --- gcc-4.0.2.orig/configure.in 2005-09-13 09:01:28.000000000 +0200 +++ gcc-4.0.2/configure.in 2006-03-10 19:37:15.000000000 +0100 @@ -368,12 +368,8 @@ *-*-chorusos) noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}" ;; - powerpc-*-darwin*) - noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes gdb gprof" - ;; *-*-darwin*) noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes gdb gprof" - noconfigdirs="$noconfigdirs ${libgcj}" ;; *-*-freebsd[[12]] | *-*-freebsd[[12]].* | *-*-freebsd*aout*) noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}" diff -ru gcc-4.0.2.orig/libffi/configure gcc-4.0.2/libffi/configure --- gcc-4.0.2.orig/libffi/configure 2005-09-28 08:16:38.000000000 +0200 +++ gcc-4.0.2/libffi/configure 2006-03-10 19:40:14.000000000 +0100 @@ -5320,6 +5320,7 @@ i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;; i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; +i*86-*-darwin*) TARGET=X86; TARGETDIR=x86;; i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; diff -ru gcc-4.0.2.orig/libffi/configure.ac gcc-4.0.2/libffi/configure.ac --- gcc-4.0.2.orig/libffi/configure.ac 2005-08-19 16:57:22.000000000 +0200 +++ gcc-4.0.2/libffi/configure.ac 2006-03-10 19:40:29.000000000 +0100 @@ -46,6 +46,7 @@ i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;; i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; +i*86-*-darwin*) TARGET=X86; TARGETDIR=x86;; i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; diff -ru gcc-4.0.2.orig/libffi/src/prep_cif.c gcc-4.0.2/libffi/src/prep_cif.c --- gcc-4.0.2.orig/libffi/src/prep_cif.c 2004-03-19 23:34:17.000000000 +0100 +++ gcc-4.0.2/libffi/src/prep_cif.c 2006-03-15 21:06:06.000000000 +0100 @@ -119,7 +119,10 @@ #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif +#ifdef __APPLE__ + && (cif->rtype->size > 8) ) +#endif bytes = STACK_ARG_SIZE(sizeof(void*)); #endif diff -ru gcc-4.0.2.orig/libffi/src/x86/ffi.c gcc-4.0.2/libffi/src/x86/ffi.c --- gcc-4.0.2.orig/libffi/src/x86/ffi.c 2004-03-16 20:17:33.000000000 +0100 +++ gcc-4.0.2/libffi/src/x86/ffi.c 2006-03-19 08:49:42.000000000 +0100 @@ -121,7 +121,7 @@ switch (cif->rtype->type) { case FFI_TYPE_VOID: -#ifndef X86_WIN32 +#if !defined X86_WIN32 && !defined __APPLE__ case FFI_TYPE_STRUCT: #endif case FFI_TYPE_SINT64: @@ -135,7 +135,7 @@ cif->flags = FFI_TYPE_SINT64; break; -#ifdef X86_WIN32 +#if defined X86_WIN32 || defined __APPLE__ case FFI_TYPE_STRUCT: if (cif->rtype->size == 1) { @@ -165,6 +165,10 @@ break; } +#ifdef __APPLE__ + cif->bytes = (cif->bytes + 15) & ~0xF; +#endif + return FFI_OK; } @@ -301,7 +305,7 @@ : : "r"(resp) : "eax", "edx"); } -#ifdef X86_WIN32 +#if defined X86_WIN32 || defined __APPLE__ else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct */ { asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax"); @@ -310,6 +314,16 @@ { asm ("movswl (%0),%%eax" : : "r" (resp) : "eax"); } +#if defined __APPLE__ + else if (rtype == FFI_TYPE_STRUCT) + { + asm ("lea -8(%ebp),%esp;" + "pop %esi;" + "pop %edi;" + "pop %ebp;" + "ret $4"); + } +#endif #endif } diff -ru gcc-4.0.2.orig/libffi/src/x86/sysv.S gcc-4.0.2/libffi/src/x86/sysv.S --- gcc-4.0.2.orig/libffi/src/x86/sysv.S 2003-10-21 21:01:58.000000000 +0200 +++ gcc-4.0.2/libffi/src/x86/sysv.S 2006-03-19 08:47:38.000000000 +0100 @@ -31,18 +31,34 @@ .text +#ifdef __APPLE__ +.globl _ffi_prep_args +#else .globl ffi_prep_args +#endif + .align 4 +#ifdef __APPLE__ +.globl _ffi_call_SYSV +#else .globl ffi_call_SYSV .type ffi_call_SYSV,@function +#endif +#ifdef __APPLE__ +_ffi_call_SYSV: +#else ffi_call_SYSV: +#endif .LFB1: pushl %ebp .LCFI0: movl %esp,%ebp .LCFI1: +#ifdef __APPLE__ + subl $8,%esp +#endif /* Make room for all of the new args. */ movl 16(%ebp),%ecx subl %ecx,%esp @@ -50,12 +66,19 @@ movl %esp,%eax /* Place all of the ffi_prep_args in position */ +#ifdef __APPLE__ + subl $8,%esp +#endif pushl 12(%ebp) pushl %eax call *8(%ebp) /* Return stack