diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 18:53:06 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 18:53:06 +0400 |
commit | c54ab76944b4f3354672dcf380be366f271690ad (patch) | |
tree | 059ebd3998f749531e0d901a6f07f2f6f0a16946 | |
parent | d5f2fccca2cbc96bb292688344d16f0309667263 (diff) | |
download | bdwgc-c54ab76944b4f3354672dcf380be366f271690ad.tar.gz |
gc6.6 tarball importgc6_6
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | Makefile.in | 7 | ||||
-rw-r--r-- | alpha_mach_dep.S | 25 | ||||
-rwxr-xr-x | configure | 113 | ||||
-rw-r--r-- | configure.in | 15 | ||||
-rw-r--r-- | doc/Makefile.in | 2 | ||||
-rw-r--r-- | doc/README | 2 | ||||
-rw-r--r-- | doc/README.changes | 24 | ||||
-rw-r--r-- | doc/README.linux | 4 | ||||
-rw-r--r-- | dyn_load.c | 29 | ||||
-rw-r--r-- | include/Makefile.in | 2 | ||||
-rw-r--r-- | include/private/gc_priv.h | 21 | ||||
-rw-r--r-- | include/private/gcconfig.h | 39 | ||||
-rw-r--r-- | include/private/pthread_stop_world.h | 1 | ||||
-rw-r--r-- | mach_dep.c | 4 | ||||
-rw-r--r-- | os_dep.c | 86 | ||||
-rw-r--r-- | pthread_stop_world.c | 62 | ||||
-rw-r--r-- | pthread_support.c | 10 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rwxr-xr-x | win32_threads.c | 9 |
20 files changed, 325 insertions, 142 deletions
diff --git a/Makefile.am b/Makefile.am index 7ce69351..89594f9d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -105,10 +105,18 @@ include/gc_pthread_redirects.h include/gc_config_macros.h \ include/gc_mark.h @addincludes@ ## FIXME: we shouldn't have to do this, but automake forces us to. +if COMPILER_XLC + ## XLC neither requires nor tolerates the unnecessary assembler goop + ASM_CPP_OPTIONS = +else + ## We use -Wp,-P to strip #line directives. Irix `as' chokes on + ## these. + ASM_CPP_OPTIONS = -Wp,-P -x assembler-with-cpp +endif .s.lo: ## We use -Wp,-P to strip #line directives. Irix `as' chokes on ## these. - $(LTCOMPILE) -Wp,-P -x assembler-with-cpp -c $< + $(LTCOMPILE) $(ASM_CPP_OPTIONS) -c $< ## We have our own definition of LTCOMPILE because we want to use our ## CFLAGS, not those passed in from the top level make. diff --git a/Makefile.in b/Makefile.in index 5a73b024..c89c84cb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -171,6 +171,8 @@ CCAS = @CCAS@ CCASFLAGS = @CCASFLAGS@ $(DEFS) CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +COMPILER_XLC_FALSE = @COMPILER_XLC_FALSE@ +COMPILER_XLC_TRUE = @COMPILER_XLC_TRUE@ CPLUSPLUS_FALSE = @CPLUSPLUS_FALSE@ CPLUSPLUS_TRUE = @CPLUSPLUS_TRUE@ CPP = @CPP@ @@ -359,6 +361,8 @@ test_cpp_SOURCES = tests/test_cpp.cc test_cpp_LDADD = ./libgc.la ./libgccpp.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) TESTS = gctest $(extra_checks) all_objs = @addobjs@ $(libgc_la_OBJECTS) +@COMPILER_XLC_FALSE@ASM_CPP_OPTIONS = -Wp,-P -x assembler-with-cpp +@COMPILER_XLC_TRUE@ASM_CPP_OPTIONS = LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) @@ -1051,9 +1055,8 @@ $(all_objs) : include/private/gcconfig.h include/private/gc_priv.h \ include/private/gc_hdrs.h include/gc.h include/gc_gcj.h \ include/gc_pthread_redirects.h include/gc_config_macros.h \ include/gc_mark.h @addincludes@ - .s.lo: - $(LTCOMPILE) -Wp,-P -x assembler-with-cpp -c $< + $(LTCOMPILE) $(ASM_CPP_OPTIONS) -c $< # # :GOTCHA: GNU make rule for making .s out of .S is flawed, diff --git a/alpha_mach_dep.S b/alpha_mach_dep.S index 53547307..d4def240 100644 --- a/alpha_mach_dep.S +++ b/alpha_mach_dep.S @@ -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 @@ GC_push_regs: .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 @@ GC_push_regs: 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 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.in Revision: 1.2 . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for gc 6.5. +# Generated by GNU Autoconf 2.59 for gc 6.6. # # Report bugs to <Hans.Boehm@hp.com>. # @@ -429,8 +429,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='gc' PACKAGE_TARNAME='gc' -PACKAGE_VERSION='6.5' -PACKAGE_STRING='gc 6.5' +PACKAGE_VERSION='6.6' +PACKAGE_STRING='gc 6.6' PACKAGE_BUGREPORT='Hans.Boehm@hp.com' ac_unique_file="gcj_mlc.c" @@ -471,7 +471,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar GC_VERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CCAS CCASFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS THREADDLLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all CPLUSPLUS_TRUE CPLUSPLUS_FALSE INCLUDES CXXINCLUDES addobjs addincludes addlibs addtests LN_S ECHO CPP EGREP LIBTOOL MY_CFLAGS UNWINDLIBS USE_LIBDIR_TRUE USE_LIBDIR_FALSE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar GC_VERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CCAS CCASFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS THREADDLLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE COMPILER_XLC_TRUE COMPILER_XLC_FALSE EXTRA_TEST_LIBS target_all CPLUSPLUS_TRUE CPLUSPLUS_FALSE INCLUDES CXXINCLUDES addobjs addincludes addlibs addtests LN_S ECHO CPP EGREP LIBTOOL MY_CFLAGS UNWINDLIBS USE_LIBDIR_TRUE USE_LIBDIR_FALSE LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -956,7 +956,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures gc 6.5 to adapt to many kinds of systems. +\`configure' configures gc 6.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1023,7 +1023,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of gc 6.5:";; + short | recursive ) echo "Configuration of gc 6.6:";; esac cat <<\_ACEOF @@ -1167,7 +1167,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -gc configure 6.5 +gc configure 6.6 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -1181,7 +1181,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by gc $as_me 6.5, which was +It was created by gc $as_me 6.6, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1953,7 +1953,7 @@ fi # Define the identity of the package. PACKAGE='gc' - VERSION='6.5' + VERSION='6.6' cat >>confdefs.h <<_ACEOF @@ -4184,13 +4184,83 @@ else fi +echo "$as_me:$LINENO: checking for xlc" >&5 +echo $ECHO_N "checking for xlc... $ECHO_C" >&6 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + #ifndef __xlC__ + # error + #endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + compiler_xlc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +compiler_xlc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $compiler_xlc" >&5 +echo "${ECHO_T}$compiler_xlc" >&6 + + +if test $compiler_xlc = yes; then + COMPILER_XLC_TRUE= + COMPILER_XLC_FALSE='#' +else + COMPILER_XLC_TRUE='#' + COMPILER_XLC_FALSE= +fi + +if test $compiler_xlc = yes -a "$powerpc_darwin" = true; then + # the darwin stack-frame-walking code is completely broken on xlc + cat >>confdefs.h <<\_ACEOF +#define DARWIN_DONT_PARSE_STACK 1 +_ACEOF + +fi + # We never want libdl on darwin. It is a fake libdl that just ends up making # dyld calls anyway case "$host" in *-*-darwin*) ;; *) - -echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -5982,7 +6052,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 5985 "configure"' > conftest.$ac_ext + echo '#line 6055 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6555,7 +6625,7 @@ chmod -w . save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" compiler_c_o=no -if { (eval echo configure:6558: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then +if { (eval echo configure:6628: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s out/conftest.err; then @@ -8482,7 +8552,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 8485 "configure" +#line 8555 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -8580,7 +8650,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 8583 "configure" +#line 8653 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9910,6 +9980,13 @@ echo "$as_me: error: conditional \"POWERPC_DARWIN\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${COMPILER_XLC_TRUE}" && test -z "${COMPILER_XLC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"COMPILER_XLC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"COMPILER_XLC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${CPLUSPLUS_TRUE}" && test -z "${CPLUSPLUS_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"CPLUSPLUS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -10195,7 +10272,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by gc $as_me 6.5, which was +This file was extended by gc $as_me 6.6, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -10253,7 +10330,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -gc config.status 6.5 +gc config.status 6.6 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -10528,6 +10605,8 @@ s,@GC_CFLAGS@,$GC_CFLAGS,;t t s,@THREADDLLIBS@,$THREADDLLIBS,;t t s,@POWERPC_DARWIN_TRUE@,$POWERPC_DARWIN_TRUE,;t t s,@POWERPC_DARWIN_FALSE@,$POWERPC_DARWIN_FALSE,;t t +s,@COMPILER_XLC_TRUE@,$COMPILER_XLC_TRUE,;t t +s,@COMPILER_XLC_FALSE@,$COMPILER_XLC_FALSE,;t t s,@EXTRA_TEST_LIBS@,$EXTRA_TEST_LIBS,;t t s,@target_all@,$target_all,;t t s,@CPLUSPLUS_TRUE@,$CPLUSPLUS_TRUE,;t t diff --git a/configure.in b/configure.in index 1fd9ece1..d81e2eaf 100644 --- a/configure.in +++ b/configure.in @@ -17,7 +17,7 @@ dnl Process this file with autoconf to produce configure. # Initialization # ============== -AC_INIT(gc,6.5,Hans.Boehm@hp.com) +AC_INIT(gc,6.6,Hans.Boehm@hp.com) ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)? AC_CONFIG_SRCDIR(gcj_mlc.c) AC_CANONICAL_TARGET @@ -184,6 +184,19 @@ case "$host" in esac AM_CONDITIONAL(POWERPC_DARWIN,test x$powerpc_darwin = xtrue) +AC_MSG_CHECKING(for xlc) +AC_TRY_COMPILE([],[ + #ifndef __xlC__ + # error + #endif +], [compiler_xlc=yes], [compiler_xlc=no]) +AC_MSG_RESULT($compiler_xlc) +AM_CONDITIONAL(COMPILER_XLC,test $compiler_xlc = yes) +if test $compiler_xlc = yes -a "$powerpc_darwin" = true; then + # the darwin stack-frame-walking code is completely broken on xlc + AC_DEFINE(DARWIN_DONT_PARSE_STACK) +fi + # We never want libdl on darwin. It is a fake libdl that just ends up making # dyld calls anyway case "$host" in diff --git a/doc/Makefile.in b/doc/Makefile.in index c712a665..179cfade 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -86,6 +86,8 @@ CCAS = @CCAS@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +COMPILER_XLC_FALSE = @COMPILER_XLC_FALSE@ +COMPILER_XLC_TRUE = @COMPILER_XLC_TRUE@ CPLUSPLUS_FALSE = @CPLUSPLUS_FALSE@ CPLUSPLUS_TRUE = @CPLUSPLUS_TRUE@ CPP = @CPP@ @@ -28,7 +28,7 @@ are GPL'ed, but with an exception that should cover all uses in the collector. (If you are concerned about such things, I recommend you look at the notice in config.guess or ltmain.sh.) -This is version 6.5 of a conservative garbage collector for C and C++. +This is version 6.6 of a conservative garbage collector for C and C++. You might find a more recent version of this at diff --git a/doc/README.changes b/doc/README.changes index 0bb4df51..97b0b684 100644 --- a/doc/README.changes +++ b/doc/README.changes @@ -2221,6 +2221,30 @@ Since GC6.4: - Fix stack_size assertion in GC_pthread_create. - Fix assertion in GC_steal_mark_stack. +Since 6.5 + - Fix CPU count detection for Irix and FreeBSD. (Thanks to Dan Bonachea.) + - Integrate Dan Bonachea's patch for the IBM XLC compiler on Darwin. + - Integrated Andreas Tobler's FreeBSD/PowerPC patch. + - Don't access the GC thread structure from the restart handler. It's + unsafe, since the handler may run too late. (Thanks to Ben Maurer for + tracking this down.) + - Applied Christian Thalinger's patch to change comment syntax in + alpha_mach_dep.S. + - Added test for GC_no_dls in GC_dyld_image_add for DARWIN. (Thanks to + Juan Jose Garcia Ripoli). + - Use LINUX_STACKBOTTOM for Linux/SH and LINUX/ARM. (Thanks to Sugioka + Toshinobu and Christian Thalinger.) + - Rewrote GC_parse_map_entry. This assumed a fixed column layout of + /proc/self/maps on Linux. This ceased to be true about 2 years ago. + The old code is probably quite problemetic with -DREDIRECT_MALLOC. It + is also used by default for IA64, though I haven't seen actual failures + there. + - More consistently define HBLKSIZE to 4096 on 64 bit architectures with + 4K pages. (Thanks to Andrew Haley.) + - With win32 threads, GC_stop_world needs to acquire GC_write_cs. (Thanks + to Ben Hutchings for the observation and patch.) + - Move up struct callinfo declaration to make gcc 4.0.2. happy. + To do: - The USE_MUNMAP code should really use a separate data structure indexed by physical page to keep track of time since last use of diff --git a/doc/README.linux b/doc/README.linux index 1d0fd4c3..ec4e7e64 100644 --- a/doc/README.linux +++ b/doc/README.linux @@ -19,10 +19,10 @@ Linux threads. These should not be touched by the client program. To use threads, you need to abide by the following requirements: -1) You need to use LinuxThreads (which are included in libc6). +1) You need to use LinuxThreads or NPTL (which are included in libc6). The collector relies on some implementation details of the LinuxThreads - package. It is unlikely that this code will work on other + package. This code may not work on other pthread implementations (in particular it will *not* work with MIT pthreads). @@ -1141,21 +1141,22 @@ static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) { 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;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) { sec = getsectbynamefromheader( hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect); - 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", + 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 */ @@ -1168,15 +1169,15 @@ static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) { 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 --git a/include/Makefile.in b/include/Makefile.in index 1f6c7d27..271ad358 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -88,6 +88,8 @@ CCAS = @CCAS@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +COMPILER_XLC_FALSE = @COMPILER_XLC_FALSE@ +COMPILER_XLC_TRUE = @COMPILER_XLC_TRUE@ CPLUSPLUS_FALSE = @CPLUSPLUS_FALSE@ CPLUSPLUS_TRUE = @CPLUSPLUS_TRUE@ CPP = @CPP@ diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index e5bd52b6..3d634cee 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -258,17 +258,6 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ /* */ /*********************************/ -#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 */ @@ -282,6 +271,16 @@ void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES])); }; #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 + /*********************************/ /* */ diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 9546c206..c028e5db 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -249,6 +249,10 @@ # define POWERPC # define mach_type_known # endif +# if defined(FREEBSD) && (defined(powerpc) || defined(__powerpc__)) +# define POWERPC +# define mach_type_known +# endif # if defined(LINUX) && defined(__mc68000__) # define M68K # define mach_type_known @@ -767,6 +771,9 @@ # if defined(__powerpc64__) # define ALIGNMENT 8 # define CPP_WORDSZ 64 +# ifndef HBLKSIZE +# define HBLKSIZE 4096 +# endif # else # define ALIGNMENT 4 # endif @@ -814,6 +821,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" @@ -1739,12 +1762,14 @@ # 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" @@ -1784,7 +1809,7 @@ # endif # ifdef LINUX # define OS_TYPE "LINUX" -# define HEURISTIC1 +# define LINUX_STACKBOTTOM # undef STACK_GRAN # define STACK_GRAN 0x10000000 # define USE_GENERIC_PUSH_REGS @@ -1849,7 +1874,7 @@ # endif # ifdef LINUX # define OS_TYPE "LINUX" -# define STACKBOTTOM ((ptr_t) 0x7c000000) +# define LINUX_STACKBOTTOM # define USE_GENERIC_PUSH_REGS # define DYNAMIC_LOADING # define SEARCH_FOR_DATA_START diff --git a/include/private/pthread_stop_world.h b/include/private/pthread_stop_world.h index 054c7a0e..6f9197a1 100644 --- a/include/private/pthread_stop_world.h +++ b/include/private/pthread_stop_world.h @@ -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. */ @@ -27,6 +27,10 @@ # endif # endif +#if defined(RS6000) || defined(POWERPC) +# include <ucontext.h> +#endif + #if defined(__MWERKS__) && !defined(POWERPC) asm static void PushMacRegisters() @@ -60,6 +60,10 @@ # include <signal.h> # endif +#if defined(LINUX) || defined(LINUX_STACKBOTTOM) +# include <ctype.h> +#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 <machine/trap.h> # if !defined(PCR) # define NEED_FIND_LIMIT @@ -245,30 +249,11 @@ word GC_apply_to_maps(word (*fn)(char *)) // 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,36 +262,46 @@ word GC_apply_to_maps(word (*fn)(char *)) char *GC_parse_map_entry(char *buf_ptr, word *start, word *end, char *prot_buf, unsigned int *maj_dev) { - 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. */ @@ -855,7 +850,6 @@ ptr_t GC_get_stack_base() #include <sys/types.h> #include <sys/stat.h> -#include <ctype.h> # define STAT_SKIP 27 /* Number of fields preceding startstack */ /* field in /proc/self/stat */ @@ -1395,7 +1389,7 @@ int * etext_addr; } # 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 */ diff --git a/pthread_stop_world.c b/pthread_stop_world.c index d301f643..b9034dc7 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -7,6 +7,11 @@ #include <semaphore.h> #include <errno.h> #include <unistd.h> +#include <sys/time.h> +#ifndef HPUX +# include <sys/select.h> + /* Doesn't exist on HP/UX 11.11. */ +#endif #if DEBUG_THREADS @@ -66,7 +71,22 @@ void GC_remove_allowed_signals(sigset_t *set) 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; @@ -175,16 +195,26 @@ void GC_suspend_handler_inner(ptr_t sig_arg) /* 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); @@ -194,20 +224,11 @@ void GC_suspend_handler_inner(ptr_t sig_arg) 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 @@ -360,6 +381,7 @@ void GC_stop_world() /* 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) { @@ -422,6 +444,7 @@ void GC_start_world() 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) { @@ -431,8 +454,7 @@ void GC_start_world() #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 --git a/pthread_support.c b/pthread_support.c index 5eba6f7a..5b3808e7 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -116,7 +116,7 @@ # include <semaphore.h> #endif /* !GC_DARWIN_THREADS */ -#if defined(GC_DARWIN_THREADS) +#if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) # include <sys/sysctl.h> #endif /* GC_DARWIN_THREADS */ @@ -877,11 +877,11 @@ void GC_thr_init() GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN); if (GC_nprocs <= 0) GC_nprocs = 1; # endif -# if defined(GC_FREEBSD_THREADS) || defined(GC_IRIX_THREADS) - /* FIXME: For Irix, that's a ridiculous assumption. */ - 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); @@ -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 5 +#define GC_TMP_VERSION_MINOR 6 #define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA #ifndef GC_NOT_ALPHA diff --git a/win32_threads.c b/win32_threads.c index 9fa75a4c..ba53d86f 100755 --- a/win32_threads.c +++ b/win32_threads.c @@ -233,6 +233,9 @@ void GC_push_thread_structures GC_PROTO((void)) # endif } +/* Defined in misc.c */ +extern CRITICAL_SECTION GC_write_cs; + void GC_stop_world() { DWORD thread_id = GetCurrentThreadId(); @@ -241,6 +244,9 @@ void GC_stop_world() 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) { @@ -271,6 +277,9 @@ void GC_stop_world() # endif thread_table[i].suspended = TRUE; } +# ifndef CYGWIN32 + LeaveCriticalSection(&GC_write_cs); +# endif /* !CYGWIN32 */ } void GC_start_world() |