dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/libgc depcomp,NONE,1.1 missing,NONE,1.1


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/libgc depcomp,NONE,1.1 missing,NONE,1.1 Makefile.am,1.2,1.3 Makefile.direct,1.2,1.3 Makefile.dj,1.2,1.3 Makefile.in,1.3,1.4 acinclude.m4,1.1.1.1,1.2 aclocal.m4,1.1.1.1,1.2 allchblk.c,1.2,1.3 alloc.c,1.2,1.3 alpha_mach_dep.S,1.1,1.2 backgraph.c,1.1,1.2 config.guess,1.2,1.3 config.sub,1.2,1.3 configure,1.2,1.3 configure.host,1.2,1.3 configure.in,1.2,1.3 dbg_mlc.c,1.2,1.3 dyn_load.c,1.2,1.3 finalize.c,1.2,1.3 gc_cpp.cc,1.2,1.3 gc_dlopen.c,1.2,1.3 if_mach.c,1.1.1.1,1.2 install-sh,1.1.1.1,1.2 irix_threads.c,1.2,1.3 linux_threads.c,1.2,1.3 mach_dep.c,1.2,1.3 malloc.c,1.2,1.3 mallocx.c,1.2,1.3 mark.c,1.4,1.5 mark_rts.c,1.2,1.3 misc.c,1.4,1.5 mkinstalldirs,1.1.1.1,1.2 os_dep.c,1.2,1.3 reclaim.c,1.2,1.3 solaris_threads.c,1.2,1.3 threadlibs.c,1.2,1.3 typd_mlc.c,1.1.1.1,1.2 version.h,1.2,1.3 win32_threads.c,1.3,1.4
Date: Wed, 05 Feb 2003 20:35:49 -0500

Update of /cvsroot/dotgnu-pnet/pnet/libgc
In directory subversions:/tmp/cvs-serv32390/libgc

Modified Files:
        Makefile.am Makefile.direct Makefile.dj Makefile.in 
        acinclude.m4 aclocal.m4 allchblk.c alloc.c alpha_mach_dep.S 
        backgraph.c config.guess config.sub configure configure.host 
        configure.in dbg_mlc.c dyn_load.c finalize.c gc_cpp.cc 
        gc_dlopen.c if_mach.c install-sh irix_threads.c 
        linux_threads.c mach_dep.c malloc.c mallocx.c mark.c 
        mark_rts.c misc.c mkinstalldirs os_dep.c reclaim.c 
        solaris_threads.c threadlibs.c typd_mlc.c version.h 
        win32_threads.c 
Added Files:
        depcomp missing 
Log Message:


Update the libgc library using gc6.2alpha3 from the libgc ftp site.


--- NEW FILE ---
#! /bin/sh

# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000 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.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

# Originally written by Alexandre Oliva <address@hidden>.

if test -z "$depmode" || test -z "$source" || test -z "$object"; then
  echo "depcomp: Variables source, object and depmode must be set" 1>&2
  exit 1
fi
# `libtool' can also be set to `yes' or `no'.

if test -z "$depfile"; then
   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
   dir=`echo "$object" | sed 's,/.*$,/,'`
   if test "$dir" = "$object"; then
      dir=
   fi
   # FIXME: should be _deps on DOS.
   depfile="$dir.deps/$base"
fi

tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}

rm -f "$tmpdepfile"

# Some modes work just like other modes, but use different flags.  We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write.  Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
  # HP compiler uses -M and no extra arg.
  gccflag=-M
  depmode=gcc
fi

if test "$depmode" = dashXmstdout; then
   # This is just like dashmstdout with a different argument.
   dashmflag=-xM
   depmode=dashmstdout
fi

case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff.  Hmm.
  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
  stat=$?
  if test $stat -eq 0; then :
  else
    rm -f "$tmpdepfile"
    exit $stat
  fi
  mv "$tmpdepfile" "$depfile"
  ;;

gcc)
## There are various ways to get dependency output from gcc.  Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
##   up in a subdir.  Having to rename by hand is ugly.
##   (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
##   -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
##   than renaming).
  if test -z "$gccflag"; then
    gccflag=-MD,
  fi
  "$@" -Wp,"$gccflag$tmpdepfile"
  stat=$?
  if test $stat -eq 0; then :
  else
    rm -f "$tmpdepfile"
    exit $stat
  fi
  rm -f "$depfile"
  echo "$object : \\" > "$depfile"
  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
  sed -e 's/^[^:]*: / /' \
      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header).  We avoid this by adding
## dummy dependencies for each header file.  Too bad gcc doesn't do
## this for us directly.
  tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'.  On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly.  Breaking it into two sed invocations is a workaround.
    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
  rm -f "$tmpdepfile"
  ;;

hp)
  # This case exists only to let depend.m4 do its work.  It works by
  # looking at the text of this script.  This case will never be run,
  # since it is checked for above.
  exit 1
  ;;

sgi)
  if test "$libtool" = yes; then
    "$@" "-Wp,-MDupdate,$tmpdepfile"
  else
    "$@" -MDupdate "$tmpdepfile"
  fi
  stat=$?
  if test $stat -eq 0; then :
  else
    rm -f "$tmpdepfile"
    exit $stat
  fi
  rm -f "$depfile"

  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
    echo "$object : \\" > "$depfile"

    # Clip off the initial element (the dependent).  Don't try to be
    # clever and replace this with sed code, as IRIX sed won't handle
    # lines with more than a fixed number of characters (4096 in
    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
    # the IRIX cc adds comments like `#:fec' to the end of the
    # dependency line.
    tr ' ' '
' < "$tmpdepfile" \
    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
    tr '
' ' ' >> $depfile
    echo >> $depfile

    # The second pass generates a dummy entry for each header file.
    tr ' ' '
' < "$tmpdepfile" \
   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
   >> $depfile
  else
    # The sourcefile does not contain any dependencies, so just
    # store a dummy comment line, to avoid errors with the Makefile
    # "include basename.Plo" scheme.
    echo "#dummy" > "$depfile"
  fi
  rm -f "$tmpdepfile"
  ;;

aix)
  # The C for AIX Compiler uses -M and outputs the dependencies
  # in a .u file.  This file always lives in the current directory.
  # Also, the AIX compiler puts `$object:' at the start of each line;
  # $object doesn't have directory information.
  stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
  tmpdepfile="$stripped.u"
  outname="$stripped.o"
  if test "$libtool" = yes; then
    "$@" -Wc,-M
  else
    "$@" -M
  fi

  stat=$?
  if test $stat -eq 0; then :
  else
    rm -f "$tmpdepfile"
    exit $stat
  fi

  if test -f "$tmpdepfile"; then
    # Each line is of the form `foo.o: dependent.h'.
    # Do two passes, one to just change these to
    # `$object: dependent.h' and one to simply `dependent.h:'.
    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
  else
    # The sourcefile does not contain any dependencies, so just
    # store a dummy comment line, to avoid errors with the Makefile
    # "include basename.Plo" scheme.
    echo "#dummy" > "$depfile"
  fi
  rm -f "$tmpdepfile"
  ;;

tru64)
   # The Tru64 compiler uses -MD to generate dependencies as a side
   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put 
   # dependencies in `foo.d' instead, so we check for that too.
   # Subdirectories are respected.

   base=`echo "$object" | sed -e 's/\.o$//' -e 's/\.lo$//'`
   tmpdepfile1="$base.o.d"
   tmpdepfile2="$base.d"
   if test "$libtool" = yes; then
      "$@" -Wc,-MD
   else
      "$@" -MD
   fi

   stat=$?
   if test $stat -eq 0; then :
   else
      rm -f "$tmpdepfile1" "$tmpdepfile2"
      exit $stat
   fi

   if test -f "$tmpdepfile1"; then
      tmpdepfile="$tmpdepfile1"
   else
      tmpdepfile="$tmpdepfile2"
   fi
   if test -f "$tmpdepfile"; then
      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
      # That's a space and a tab in the [].
      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
   else
      echo "#dummy" > "$depfile"
   fi
   rm -f "$tmpdepfile"
   ;;

#nosideeffect)
  # This comment above is used by automake to tell side-effect
  # dependency tracking mechanisms from slower ones.

dashmstdout)
  # Important note: in order to support this mode, a compiler *must*
  # always write the proprocessed file to stdout, regardless of -o,
  # because we must use -o when running libtool.
  test -z "$dashmflag" && dashmflag=-M
  ( IFS=" "
    case " $* " in
    *" --mode=compile "*) # this is libtool, let us make it quiet
      for arg
      do # cycle over the arguments
        case "$arg" in
        "--mode=compile")
          # insert --quiet before "--mode=compile"
          set fnord "$@" --quiet
          shift # fnord
          ;;
        esac
        set fnord "$@" "$arg"
        shift # fnord
        shift # "$arg"
      done
      ;;
    esac
    "$@" $dashmflag | sed 's:^[^:]*\:[  ]*:'"$object"'\: :' > "$tmpdepfile"
  ) &
  proc=$!
  "$@"
  stat=$?
  wait "$proc"
  if test "$stat" != 0; then exit $stat; fi
  rm -f "$depfile"
  cat < "$tmpdepfile" > "$depfile"
  tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly.  Breaking it into two sed invocations is a workaround.
    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
  rm -f "$tmpdepfile"
  ;;

dashXmstdout)
  # This case only exists to satisfy depend.m4.  It is never actually
  # run, as this mode is specially recognized in the preamble.
  exit 1
  ;;

makedepend)
  # X makedepend
  (
    shift
    cleared=no
    for arg in "$@"; do
      case $cleared in no)
        set ""; shift
        cleared=yes
      esac
      case "$arg" in
        -D*|-I*)
          set fnord "$@" "$arg"; shift;;
        -*)
          ;;
        *)
          set fnord "$@" "$arg"; shift;;
      esac
    done
    obj_suffix="`echo $object | sed 's/^.*\././'`"
    touch "$tmpdepfile"
    ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
  ) &
  proc=$!
  "$@"
  stat=$?
  wait "$proc"
  if test "$stat" != 0; then exit $stat; fi
  rm -f "$depfile"
  cat < "$tmpdepfile" > "$depfile"
  sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly.  Breaking it into two sed invocations is a workaround.
    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
  rm -f "$tmpdepfile" "$tmpdepfile".bak
  ;;

cpp)
  # Important note: in order to support this mode, a compiler *must*
  # always write the proprocessed file to stdout, regardless of -o,
  # because we must use -o when running libtool.
  ( IFS=" "
    case " $* " in
    *" --mode=compile "*)
      for arg
      do # cycle over the arguments
        case $arg in
        "--mode=compile")
          # insert --quiet before "--mode=compile"
          set fnord "$@" --quiet
          shift # fnord
          ;;
        esac
        set fnord "$@" "$arg"
        shift # fnord
        shift # "$arg"
      done
      ;;
    esac
    "$@" -E |
    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
    sed '$ s: \\$::' > "$tmpdepfile"
  ) &
  proc=$!
  "$@"
  stat=$?
  wait "$proc"
  if test "$stat" != 0; then exit $stat; fi
  rm -f "$depfile"
  echo "$object : \\" > "$depfile"
  cat < "$tmpdepfile" >> "$depfile"
  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
  rm -f "$tmpdepfile"
  ;;

msvisualcpp)
  # Important note: in order to support this mode, a compiler *must*
  # always write the proprocessed file to stdout, regardless of -o,
  # because we must use -o when running libtool.
  ( IFS=" "
    case " $* " in
    *" --mode=compile "*)
      for arg
      do # cycle over the arguments
        case $arg in
        "--mode=compile")
          # insert --quiet before "--mode=compile"
          set fnord "$@" --quiet
          shift # fnord
          ;;
        esac
        set fnord "$@" "$arg"
        shift # fnord
        shift # "$arg"
      done
      ;;
    esac
    for arg
    do
      case "$arg" in
      "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
        set fnord "$@"
        shift
        shift
        ;;
      *)
        set fnord "$@" "$arg"
        shift
        shift
        ;;
      esac
    done
    "$@" -E |
    sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' 
| sort | uniq > "$tmpdepfile"
  ) &
  proc=$!
  "$@"
  stat=$?
  wait "$proc"
  if test "$stat" != 0; then exit $stat; fi
  rm -f "$depfile"
  echo "$object : \\" > "$depfile"
  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::    \1 \\:p' >> 
"$depfile"
  echo "        " >> "$depfile"
  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> 
"$depfile"
  rm -f "$tmpdepfile"
  ;;

none)
  exec "$@"
  ;;

*)
  echo "Unknown depmode $depmode" 1>&2
  exit 1
  ;;
esac

exit 0

--- NEW FILE ---
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <address@hidden>, 1996.

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

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

if test $# -eq 0; then
  echo 1>&2 "Try \`$0 --help' for more information"
  exit 1
fi

run=:

# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
  configure_ac=configure.ac
else
  configure_ac=configure.in
fi

case "$1" in
--run)
  # Try to run requested program, and just exit if it succeeds.
  run=
  shift
  "$@" && exit 0
  ;;
esac

# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in

  -h|--h|--he|--hel|--help)
    echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...

Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.

Options:
  -h, --help      display this help and exit
  -v, --version   output version information and exit
  --run           try to run the given command, and emulate it if it fails

Supported PROGRAM values:
  aclocal      touch file \`aclocal.m4'
  autoconf     touch file \`configure'
  autoheader   touch file \`config.h.in'
  automake     touch all \`Makefile.in' files
  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
  flex         create \`lex.yy.c', if possible, from existing .c
  help2man     touch the output file
  lex          create \`lex.yy.c', if possible, from existing .c
  makeinfo     touch the output file
  tar          try tar, gnutar, gtar, then tar without non-portable flags
  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
    ;;

  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
    echo "missing 0.4 - GNU automake"
    ;;

  -*)
    echo 1>&2 "$0: Unknown \`$1' option"
    echo 1>&2 "Try \`$0 --help' for more information"
    exit 1
    ;;

  aclocal*)
    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
       # We have it, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
         to install the \`Automake' and \`Perl' packages.  Grab them from
         any GNU archive site."
    touch aclocal.m4
    ;;

  autoconf)
    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
       # We have it, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified \`${configure_ac}'.  You might want to install the
         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
         archive site."
    touch configure
    ;;

  autoheader)
    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
       # We have it, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
         from any GNU archive site."
    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' 
${configure_ac}`
    test -z "$files" && files="config.h"
    touch_files=
    for f in $files; do
      case "$f" in
      *:*) touch_files="$touch_files "`echo "$f" |
                                       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
      *) touch_files="$touch_files $f.in";;
      esac
    done
    touch $touch_files
    ;;

  automake*)
    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
       # We have it, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
         You might want to install the \`Automake' and \`Perl' packages.
         Grab them from any GNU archive site."
    find . -type f -name Makefile.am -print |
           sed 's/\.am$/.in/' |
           while read f; do touch "$f"; done
    ;;

  autom4te)
    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
       # We have it, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
         system.  You might have modified some files without having the
         proper tools for further handling them.
         You can get \`$1Help2man' as part of \`Autoconf' from any GNU
         archive site."

    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
    if test -f "$file"; then
        touch $file
    else
        test -z "$file" || exec >$file
        echo "#! /bin/sh"
        echo "# Created by GNU Automake missing as a replacement of"
        echo "#  $ $@"
        echo "exit 0"
        chmod +x $file
        exit 1
    fi
    ;;

  bison|yacc)
    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified a \`.y' file.  You may need the \`Bison' package
         in order for those modifications to take effect.  You can get
         \`Bison' from any GNU archive site."
    rm -f y.tab.c y.tab.h
    if [ $# -ne 1 ]; then
        eval LASTARG="\${$#}"
        case "$LASTARG" in
        *.y)
            SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
            if [ -f "$SRCFILE" ]; then
                 cp "$SRCFILE" y.tab.c
            fi
            SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
            if [ -f "$SRCFILE" ]; then
                 cp "$SRCFILE" y.tab.h
            fi
          ;;
        esac
    fi
    if [ ! -f y.tab.h ]; then
        echo >y.tab.h
    fi
    if [ ! -f y.tab.c ]; then
        echo 'main() { return 0; }' >y.tab.c
    fi
    ;;

  lex|flex)
    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified a \`.l' file.  You may need the \`Flex' package
         in order for those modifications to take effect.  You can get
         \`Flex' from any GNU archive site."
    rm -f lex.yy.c
    if [ $# -ne 1 ]; then
        eval LASTARG="\${$#}"
        case "$LASTARG" in
        *.l)
            SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
            if [ -f "$SRCFILE" ]; then
                 cp "$SRCFILE" lex.yy.c
            fi
          ;;
        esac
    fi
    if [ ! -f lex.yy.c ]; then
        echo 'main() { return 0; }' >lex.yy.c
    fi
    ;;

  help2man)
    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
       # We have it, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified a dependency of a manual page.  You may need the
         \`Help2man' package in order for those modifications to take
         effect.  You can get \`Help2man' from any GNU archive site."

    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
    if test -z "$file"; then
        file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
    fi
    if [ -f "$file" ]; then
        touch $file
    else
        test -z "$file" || exec >$file
        echo ".ab help2man is required to generate this page"
        exit 1
    fi
    ;;

  makeinfo)
    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
       # We have makeinfo, but it failed.
       exit 1
    fi

    echo 1>&2 "\
WARNING: \`$1' is missing on your system.  You should only need it if
         you modified a \`.texi' or \`.texinfo' file, or any other file
         indirectly affecting the aspect of the manual.  The spurious
         call might also be the consequence of using a buggy \`make' (AIX,
         DU, IRIX).  You might want to install the \`Texinfo' package or
         the \`GNU make' package.  Grab either from any GNU archive site."
    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
    if test -z "$file"; then
      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
      file=`sed -n '/address@hidden/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
    fi
    touch $file
    ;;

  tar)
    shift
    if test -n "$run"; then
      echo 1>&2 "ERROR: \`tar' requires --run"
      exit 1
    fi

    # We have already tried tar in the generic part.
    # Look for gnutar/gtar before invocation to avoid ugly error
    # messages.
    if (gnutar --version > /dev/null 2>&1); then
       gnutar ${1+"$@"} && exit 0
    fi
    if (gtar --version > /dev/null 2>&1); then
       gtar ${1+"$@"} && exit 0
    fi
    firstarg="$1"
    if shift; then
        case "$firstarg" in
        *o*)
            firstarg=`echo "$firstarg" | sed s/o//`
            tar "$firstarg" ${1+"$@"} && exit 0
            ;;
        esac
        case "$firstarg" in
        *h*)
            firstarg=`echo "$firstarg" | sed s/h//`
            tar "$firstarg" ${1+"$@"} && exit 0
            ;;
        esac
    fi

    echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
         You may want to install GNU tar or Free paxutils, or check the
         command line arguments."
    exit 1
    ;;

  *)
    echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
         system.  You might have modified some files without having the
         proper tools for further handling them.  Check the \`README' file,
         it often tells you about the needed prerequirements for installing
         this package.  You may also peek at any GNU archive site, in case
         some other package would contain this missing \`$1' program."
    exit 1
    ;;
esac

exit 0

Index: Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Makefile.am 8 Apr 2002 23:36:49 -0000       1.2
--- Makefile.am 6 Feb 2003 01:35:45 -0000       1.3
***************
*** 11,14 ****
--- 11,15 ----
  #
  # Original author: Tom Tromey
+ # Severely truncated by Hans-J. Boehm
  
  ## Process this file with automake to produce Makefile.in.
***************
*** 18,42 ****
  ## Makefile.am.
  
! AUTOMAKE_OPTIONS = cygnus
  
! # Multilib support variables.
! MULTISRCTOP =
! MULTIBUILDTOP =
! MULTIDIRS =
! MULTISUBDIR =
! MULTIDO = true
! MULTICLEAN = true
! 
! ## Install a library built with a cross compiler in tooldir, not
! ## libdir.
! if USE_LIBDIR
! toolexeclibdir = $(libdir)$(MULTISUBDIR)
! else
! toolexecdir = $(exec_prefix)/$(target_alias)
! toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
! endif
  
- toolexeclib_LTLIBRARIES = $(target_all)
- EXTRA_LTLIBRARIES = libgc.la
  libgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
  dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
--- 19,31 ----
  ## Makefile.am.
  
! AUTOMAKE_OPTIONS = foreign
  
! lib_LTLIBRARIES = libgc.la
! 
! include_HEADERS = include/gc.h include/gc_local_alloc.h \
! include/leak_detector.h include/gc_typed.h @addincludes@
! 
! EXTRA_HEADERS = include/gc_cpp.h include/gc_allocator.h
  
  libgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
  dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
***************
*** 50,79 ****
  libgc_la_LIBADD = @addobjs@ $(THREADLIBS)
  libgc_la_DEPENDENCIES = @addobjs@
! libgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
  
! EXTRA_libgc_la_SOURCES = alpha_mach_dep.s \
  mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
  rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
! sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
  
  AM_CXXFLAGS = @GC_CFLAGS@
  AM_CFLAGS = @GC_CFLAGS@
  
! check_PROGRAMS = gctest
! # The following hack produces a warning from automake, but we need it in 
order 
! # to build a file from a subdirectory. FIXME.
! test.o:       tests/test.c
!       $(COMPILE) -c tests/test.c
  #     Using $< in the above seems to fail with the HP/UX on Itanium make.
  
! gctest_OBJECTS = test.o
! gctest_LDADD = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
  TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
! TESTS = gctest
  
  ## FIXME: relies on internal code generated by automake.
  all_objs = @addobjs@ $(libgc_la_OBJECTS)
  $(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_mark.h
  
  ## FIXME: we shouldn't have to do this, but automake forces us to.
--- 39,74 ----
  libgc_la_LIBADD = @addobjs@ $(THREADLIBS)
  libgc_la_DEPENDENCIES = @addobjs@
! libgc_la_LDFLAGS = -version-info 1:2:0
  
! EXTRA_libgc_la_SOURCES = alpha_mach_dep.S \
  mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
  rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
! sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s gc_cpp.cc
  
  AM_CXXFLAGS = @GC_CFLAGS@
  AM_CFLAGS = @GC_CFLAGS@
  
! check_PROGRAMS = gctest @addtests@
! EXTRA_PROGRAMS = test_cpp
! 
! test.o:       $(srcdir)/tests/test.c
!       $(COMPILE) -c $(srcdir)/tests/test.c
  #     Using $< in the above seems to fail with the HP/UX on Itanium make.
+ test_cpp.o:   $(srcdir)/tests/test_cpp.cc
+       $(COMPILE) -c $(srcdir)/tests/test_cpp.cc
  
! # gctest_OBJECTS = test.o
! gctest_SOURCES = 
! gctest_LDADD = test.o ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
! test_cpp_SOURCES = 
! test_cpp_LDADD = test_cpp.o ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
  TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
! TESTS = gctest @addtests@
  
  ## FIXME: relies on internal code generated by automake.
  all_objs = @addobjs@ $(libgc_la_OBJECTS)
  $(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_mark.h @addincludes@
  
  ## FIXME: we shouldn't have to do this, but automake forces us to.
***************
*** 90,95 ****
  LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
  
- AM_CFLAGS = @GC_CFLAGS@
- 
  # Work around what appears to be a GNU make bug handling MAKEFLAGS
  # values defined in terms of make variables, as is the case for CC and
--- 85,88 ----
***************
*** 134,161 ****
  
  CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host
- 
- # Multilib support.
- .PHONY: all-multi mostlyclean-multi clean-multi distclean-multi \
-       maintainer-clean-multi
- 
- all-am: all-multi
- install-am: install-multi
- mostlyclean-am: mostlyclean-multi
- clean-am: clean-multi
- distclean-am: distclean-multi
- maintainer-clean-am: maintainer-clean-multi
- 
- all-multi:
-       $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do
- install-multi:
-       $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do
- mostlyclean-multi:
-       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean
- clean-multi:
-       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean
- distclean-multi:
-       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
- maintainer-clean-multi:
-       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
  
  MAKEOVERRIDES=
--- 127,130 ----

Index: Makefile.direct
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/Makefile.direct,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Makefile.direct     8 Apr 2002 23:36:49 -0000       1.2
--- Makefile.direct     6 Feb 2003 01:35:45 -0000       1.3
***************
*** 35,40 ****
  # To build the parallel collector on Linux, add to the above:
  # -DGC_LINUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC
! # To build the parallel collector n a static library on HP/UX, add to the 
above:
  # -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -DUSE_HPUX_TLS 
-D_POSIX_C_SOURCE=199506L
  
  # HOSTCC and HOSTCFLAGS are used to build executables that will be run as
--- 35,43 ----
  # To build the parallel collector on Linux, add to the above:
  # -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 -DUSE_HPUX_TLS 
-D_POSIX_C_SOURCE=199506L
+ # To build the thread-safe collector on Tru64, add to the above:
+ # -pthread -DGC_OSF1_THREADS
  
  # HOSTCC and HOSTCFLAGS are used to build executables that will be run as
***************
*** 106,116 ****
  #   This is defined implicitly in a few environments.  Must also be defined
  #   by clients that use gc_cpp.h.
! # -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be
! #   defined as aliases for X, GC_realloc, and GC_free, respectively.
  #   Calloc and strdup are redefined in terms of the new malloc.  X should
  #   be either GC_malloc or GC_malloc_uncollectable, or
  #   GC_debug_malloc_replacement.  (The latter invokes GC_debug_malloc
  #   with dummy source location information, but still results in
! #   properly remembered call stacks on Linux/X86 and Solaris/SPARC.)
  #   The former is occasionally useful for working around leaks in code
  #   you don't want to (or can't) look at.  It may not work for
--- 109,121 ----
  #   This is defined implicitly in a few environments.  Must also be defined
  #   by clients that use gc_cpp.h.
! # -DREDIRECT_MALLOC=X causes malloc to be defined as alias for X.
! #   Unless the following macros are defined, realloc is also redirected
! #   to GC_realloc, and free is redirected to GC_free.
  #   Calloc and strdup are redefined in terms of the new malloc.  X should
  #   be either GC_malloc or GC_malloc_uncollectable, or
  #   GC_debug_malloc_replacement.  (The latter invokes GC_debug_malloc
  #   with dummy source location information, but still results in
! #   properly remembered call stacks on Linux/X86 and Solaris/SPARC.
! #   It requires that the following two macros also be used.)
  #   The former is occasionally useful for working around leaks in code
  #   you don't want to (or can't) look at.  It may not work for
***************
*** 124,127 ****
--- 129,135 ----
  #   together with -DREDIRECT_MALLOC=GC_debug_malloc_replacement to
  #   generate leak reports with call stacks for both malloc and realloc.
+ #   This also requires the following:
+ # -DREDIRECT_FREE=X causes free to be redirected to X.  The
+ #   canonical use is -DREDIRECT_FREE=GC_debug_free.
  # -DIGNORE_FREE turns calls to free into a noop.  Only useful with
  #   -DREDIRECT_MALLOC.
***************
*** 242,245 ****
--- 250,268 ----
  #   from a multithreaded parent.  Currently only supported by linux_threads.c.
  #   (Similar code should work on Solaris or Irix, but it hasn't been tried.)
+ # -DTEST_WITH_SYSTEM_MALLOC causes gctest to allocate (and leak) large chunks
+ #   of memory with the standard system malloc.  This will cause the root
+ #   set and collected heap to grow significantly if malloced memory is
+ #   somehow getting traced by the collector.  This has no impact on the
+ #   generated library; it only affects the test.
+ # -DPOINTER_MASK=0x... causes candidate pointers to be ANDed with the
+ #   given mask before being considered.  If either this or the following
+ #   macro is defined, it will be assumed that all pointers stored in
+ #   the heap need to be processed this way.  Stack and register pointers
+ #   will be considered both with and without processing.
+ #   These macros are normally needed only to support systems that use
+ #   high-order pointer tags. EXPERIMENTAL.
+ # -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.
  #
  
***************
*** 283,287 ****
        doc/README.environment doc/tree.html doc/gcdescr.html \
        doc/README.autoconf doc/README.macros doc/README.ews4800 \
!       doc/README.DGUX386 doc/README.arm.cross
  
  TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
--- 306,310 ----
        doc/README.environment doc/tree.html doc/gcdescr.html \
        doc/README.autoconf doc/README.macros doc/README.ews4800 \
!       doc/README.DGUX386 doc/README.arm.cross doc/leak.html
  
  TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
***************
*** 291,295 ****
                 libtool.m4 install-sh configure.host Makefile.in \
                 ltconfig aclocal.m4 config.sub config.guess \
!                ltmain.sh mkinstalldirs
  
  OTHER_MAKEFILES= OS2_MAKEFILE NT_MAKEFILE NT_THREADS_MAKEFILE gc.mak \
--- 314,318 ----
                 libtool.m4 install-sh configure.host Makefile.in \
                 ltconfig aclocal.m4 config.sub config.guess \
!                ltmain.sh mkinstalldirs depcomp missing
  
  OTHER_MAKEFILES= OS2_MAKEFILE NT_MAKEFILE NT_THREADS_MAKEFILE gc.mak \
***************
*** 459,468 ****
            $(srcdir)/sparc_netbsd_mach_dep.s $(UTILS)
        rm -f mach_dep.o
!       ./if_mach MIPS IRIX5 $(AS) -o mach_dep.o $(srcdir)/mips_sgi_mach_dep.S
        ./if_mach MIPS RISCOS $(AS) -o mach_dep.o 
$(srcdir)/mips_ultrix_mach_dep.s
        ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o 
$(srcdir)/mips_ultrix_mach_dep.s
-       ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
        ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o 
$(srcdir)/powerpc_macosx_mach_dep.s
!       ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.S
        ./if_mach SPARC SUNOS5 $(CC) -c -o mach_dep.o $(srcdir)/sparc_mach_dep.S
        ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o 
$(srcdir)/sparc_sunos4_mach_dep.s
--- 482,491 ----
            $(srcdir)/sparc_netbsd_mach_dep.s $(UTILS)
        rm -f mach_dep.o
!       ./if_mach MIPS IRIX5 $(CC) -E $(srcdir)/mips_sgi_mach_dep.S \
!        | ./if_mach MIPS IRIX5 grep -v "^\#" > $(srcdir)/mips_sgi_mach_dep.s
        ./if_mach MIPS RISCOS $(AS) -o mach_dep.o 
$(srcdir)/mips_ultrix_mach_dep.s
        ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o 
$(srcdir)/mips_ultrix_mach_dep.s
        ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o 
$(srcdir)/powerpc_macosx_mach_dep.s
!       ./if_mach ALPHA LINUX $(CC) -c -o mach_dep.o $(srcdir)/alpha_mach_dep.S
        ./if_mach SPARC SUNOS5 $(CC) -c -o mach_dep.o $(srcdir)/sparc_mach_dep.S
        ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o 
$(srcdir)/sparc_sunos4_mach_dep.s
***************
*** 530,534 ****
        rm -f gc.a *.o *.exe tests/*.o gctest gctest_dyn_link test_cpp \
              setjmp_test  mon.out gmon.out a.out core if_not_there if_mach \
!             threadlibs $(CORD_OBJS) cord/cordtest cord/de
        -rm -f *~
  
--- 553,557 ----
        rm -f gc.a *.o *.exe tests/*.o gctest gctest_dyn_link test_cpp \
              setjmp_test  mon.out gmon.out a.out core if_not_there if_mach \
!             threadlibs $(CORD_OBJS) cord/cordtest cord/de mips_sgi_mach_dep.s
        -rm -f *~
  

Index: Makefile.dj
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/Makefile.dj,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Makefile.dj 8 Apr 2002 23:36:49 -0000       1.2
--- Makefile.dj 6 Feb 2003 01:35:45 -0000       1.3
***************
*** 153,157 ****
  
  
! CXXFLAGS= $(CFLAGS) -DOPERATOR_NEW_ARRAY
  AR= ar
  RANLIB= ranlib
--- 153,157 ----
  
  
! CXXFLAGS= $(CFLAGS) -DGC_OPERATOR_NEW_ARRAY
  AR= ar
  RANLIB= ranlib

Index: Makefile.in
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/Makefile.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** Makefile.in 10 Apr 2002 05:04:08 -0000      1.3
--- Makefile.in 6 Feb 2003 01:35:45 -0000       1.4
***************
*** 1,5 ****
! # Makefile.in generated automatically by automake 1.4 from Makefile.am
  
! # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
  # This Makefile.in is free software; the Free Software Foundation
  # gives unlimited permission to copy and/or distribute it,
--- 1,7 ----
! # Makefile.in generated by automake 1.6.1 from Makefile.am.
! # @configure_input@
  
! # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
[...1158 lines suppressed...]
!       installcheck-am installdirs maintainer-clean \
!       maintainer-clean-generic mostlyclean mostlyclean-compile \
!       mostlyclean-generic mostlyclean-libtool tags uninstall \
!       uninstall-am uninstall-includeHEADERS uninstall-info-am \
!       uninstall-libLTLIBRARIES
! 
! 
! test.o:       $(srcdir)/tests/test.c
!       $(COMPILE) -c $(srcdir)/tests/test.c
! #     Using $< in the above seems to fail with the HP/UX on Itanium make.
! test_cpp.o:   $(srcdir)/tests/test_cpp.cc
!       $(COMPILE) -c $(srcdir)/tests/test_cpp.cc
  $(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_mark.h @addincludes@
  
  .s.lo:
        $(LTCOMPILE) -Wp,-P -x assembler-with-cpp -c $<
  # Tell versions [3.59,3.63) of GNU make to not export all variables.
  # Otherwise a system limit (for SysV at least) may be exceeded.

Index: acinclude.m4
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/acinclude.m4,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** acinclude.m4        9 Nov 2001 02:20:53 -0000       1.1.1.1
--- acinclude.m4        6 Feb 2003 01:35:45 -0000       1.2
***************
*** 1,182 ****
- # Copyright (c) 1999-2001 by Red Hat, Inc. All rights reserved.
- # 
- # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
- # OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- # 
- # Permission is hereby granted to use or copy this program
- # for any purpose,  provided the above notices are retained on all copies.
- # Permission to modify the code and to distribute modified code is granted,
- # provided the above notices are retained, and a notice that the code was
- # modified is included with the above copyright notice.
- #
- # Original author: Tom Tromey
- 
- # FIXME: We temporarily define our own version of AC_PROG_CC.  This is
- # copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS.  We
- # are probably using a cross compiler, which will not be able to fully
- # link an executable.  This should really be fixed in autoconf
- # itself.
- 
- AC_DEFUN(GC_CONFIGURE,
- [
- dnl Default to --enable-multilib
- AC_ARG_ENABLE(multilib,
- [  --enable-multilib       build many library versions (default)],
- [case "${enableval}" in
-   yes) multilib=yes ;;
-   no)  multilib=no ;;
-   *)   AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
-  esac], [multilib=yes])dnl
- 
- dnl We may get other options which we don't document:
- dnl --with-target-subdir, --with-multisrctop, --with-multisubdir
- 
- dnl I needed to add the -n test to allow configuration in src directory - HB
- if test "[$]{srcdir}" = "."; then
-   if test "[$]{with_target_subdir}" != "." -a -n "[$]{with_target_subdir}"; 
then
-     gc_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1"
-   else
-     gc_basedir="[$]{srcdir}/[$]{with_multisrctop}$1"
-   fi
- else
-   gc_basedir="[$]{srcdir}/$1"
- fi
- AC_SUBST(gc_basedir)
- AC_CONFIG_AUX_DIR($gc_basedir)
- 
- AC_CANONICAL_SYSTEM
- 
- AM_INIT_AUTOMAKE(gc, 6.0, no-define)
- 
- # FIXME: We temporarily define our own version of AC_PROG_CC.  This is
- # copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS.  We
- # are probably using a cross compiler, which will not be able to fully
- # link an executable.  This should really be fixed in autoconf
- # itself.
- 
- AC_DEFUN(LIB_AC_PROG_CC,
- [AC_BEFORE([$0], [AC_PROG_CPP])dnl
- dnl Fool anybody using AC_PROG_CC.
- AC_PROVIDE([AC_PROG_CC])
- AC_CHECK_PROG(CC, gcc, gcc)
- if test -z "$CC"; then
-   AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
-   test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
- fi
- 
- AC_PROG_CC_GNU
- 
- if test $ac_cv_prog_gcc = yes; then
-   GCC=yes
- dnl Check whether -g works, even if CFLAGS is set, in case the package
- dnl plays around with CFLAGS (such as to build both debugging and
- dnl normal versions of a library), tasteless as that idea is.
-   ac_test_CFLAGS="${CFLAGS+set}"
-   ac_save_CFLAGS="$CFLAGS"
-   CFLAGS=
-   AC_PROG_CC_G
-   if test "$ac_test_CFLAGS" = set; then
-     CFLAGS="$ac_save_CFLAGS"
-   elif test $ac_cv_prog_cc_g = yes; then
-     CFLAGS="-g -O2"
-   else
-     CFLAGS="-O2"
-   fi
- else
-   GCC=
-   test "${CFLAGS+set}" = set || CFLAGS="-g"
- fi
- ])
- 
- LIB_AC_PROG_CC
- 
- # Likewise for AC_PROG_CXX.
- AC_DEFUN(LIB_AC_PROG_CXX,
- [AC_BEFORE([$0], [AC_PROG_CXXCPP])dnl
- dnl Fool anybody using AC_PROG_CXX.
- AC_PROVIDE([AC_PROG_CXX])
- AC_CHECK_PROGS(CXX, $CCC c++ g++ gcc CC cxx cc++, gcc)
- test -z "$CXX" && AC_MSG_ERROR([no acceptable c++ found in \$PATH])
- 
- AC_PROG_CXX_GNU
- 
- if test $ac_cv_prog_gxx = yes; then
-   GXX=yes
- dnl Check whether -g works, even if CXXFLAGS is set, in case the package
- dnl plays around with CXXFLAGS (such as to build both debugging and
- dnl normal versions of a library), tasteless as that idea is.
-   ac_test_CXXFLAGS="${CXXFLAGS+set}"
-   ac_save_CXXFLAGS="$CXXFLAGS"
-   CXXFLAGS=
-   AC_PROG_CXX_G
-   if test "$ac_test_CXXFLAGS" = set; then
-     CXXFLAGS="$ac_save_CXXFLAGS"
-   elif test $ac_cv_prog_cxx_g = yes; then
-     CXXFLAGS="-g -O2"
-   else
-     CXXFLAGS="-O2"
-   fi
- else
-   GXX=
-   test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
- fi
- ])
- 
- LIB_AC_PROG_CXX
- 
- # AC_CHECK_TOOL does AC_REQUIRE (AC_CANONICAL_BUILD).  If we don't
- # run it explicitly here, it will be run implicitly before
- # NEWLIB_CONFIGURE, which doesn't work because that means that it will
- # be run before AC_CANONICAL_HOST.
- AC_CANONICAL_BUILD
- 
- AC_CHECK_TOOL(AS, as)
- AC_CHECK_TOOL(AR, ar)
- AC_CHECK_TOOL(RANLIB, ranlib, :)
- 
- AC_PROG_INSTALL
- 
- AM_MAINTAINER_MODE
- 
- # We need AC_EXEEXT to keep automake happy in cygnus mode.  However,
- # at least currently, we never actually build a program, so we never
- # need to use $(EXEEXT).  Moreover, the test for EXEEXT normally
- # fails, because we are probably configuring with a cross compiler
- # which can't create executables.  So we include AC_EXEEXT to keep
- # automake happy, but we don't execute it, since we don't care about
- # the result.
- if false; then
-   # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
-   # to nothing, so nothing would remain between `then' and `fi' if it
-   # were not for the `:' below.
-   :
-   AC_EXEEXT
- fi
- 
- . [$]{srcdir}/configure.host
- 
- case [$]{gc_basedir} in
- /* | [A-Za-z]:[/\\]*) gc_flagbasedir=[$]{gc_basedir} ;;
- *) gc_flagbasedir='[$](top_builddir)/'[$]{gc_basedir} ;;
- esac
- 
- gc_cflags="[$]{gc_cflags} -I"'[$](top_builddir)'"/$1/targ-include 
-I[$]{gc_flagbasedir}/libc/include"
- case "${host}" in
-   *-*-cygwin32*)
-     gc_cflags="[$]{gc_cflags} -I[$]{gc_flagbasedir}/../winsup/include"
-     ;;
- esac
- 
- dnl gc_cflags="[$]{gc_cflags} -fno-builtin"
- 
- GC_CFLAGS=${gc_cflags}
- AC_SUBST(GC_CFLAGS)
- ]))
- 
- ))))
- 
  sinclude(libtool.m4)
- dnl The line below arranges for aclocal not to bring a definition of
- dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake
- dnl to add a definition of LIBTOOL to Makefile.in.
- ifelse(yes,no,[AC_DEFUN([AM_PROG_LIBTOOL],[AC_SUBST(LIBTOOL)])])
--- 1 ----

Index: aclocal.m4
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/aclocal.m4,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** aclocal.m4  9 Nov 2001 02:20:57 -0000       1.1.1.1
--- aclocal.m4  6 Feb 2003 01:35:45 -0000       1.2
***************
*** 1,229 ****
! dnl aclocal.m4 generated automatically by aclocal 1.4
  
! dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
! dnl This file is free software; the Free Software Foundation
! dnl gives unlimited permission to copy and/or distribute it,
! dnl with or without modifications, as long as this notice is preserved.
! 
! dnl This program is distributed in the hope that it will be useful,
! dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
! dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
[...1099 lines suppressed...]
- [AC_SUBST($1_TRUE)
- AC_SUBST($1_FALSE)
- if $2; then
-   $1_TRUE=
-   $1_FALSE='#'
- else
-   $1_TRUE='#'
-   $1_FALSE=
- fi])
  
--- 815,823 ----
        USE_MAINTAINER_MODE=$enableval,
        USE_MAINTAINER_MODE=no)
!   AC_MSG_RESULT([$USE_MAINTAINER_MODE])
!   AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
    MAINT=$MAINTAINER_MODE_TRUE
    AC_SUBST(MAINT)dnl
  ]
  )
  

Index: allchblk.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/allchblk.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** allchblk.c  8 Apr 2002 23:36:49 -0000       1.2
--- allchblk.c  6 Feb 2003 01:35:45 -0000       1.3
***************
*** 48,51 ****
--- 48,52 ----
  
  #ifndef USE_MUNMAP
+ 
    word GC_free_bytes[N_HBLK_FLS+1] = { 0 };
        /* Number of free bytes on each list.   */
***************
*** 53,57 ****
    /* Is bytes + the number of free bytes on lists n .. N_HBLK_FLS     */
    /* > GC_max_large_allocd_bytes?                                     */
!   GC_bool GC_enough_large_bytes_left(bytes,n)
    word bytes;
    int n;
--- 54,61 ----
    /* Is bytes + the number of free bytes on lists n .. N_HBLK_FLS     */
    /* > GC_max_large_allocd_bytes?                                     */
! # ifdef __GNUC__
!   __inline__
! # endif
!   static GC_bool GC_enough_large_bytes_left(bytes,n)
    word bytes;
    int n;
***************
*** 596,599 ****
--- 600,609 ----
                      continue;
                    } 
+                   /* If we are deallocating lots of memory from       */
+                   /* finalizers, fail and collect sooner rather       */
+                   /* than later.                                      */
+                   if (GC_finalizer_mem_freed > (GC_heapsize >> 4))  {
+                     continue;
+                   }
  #             endif /* !USE_MUNMAP */
            }
***************
*** 655,661 ****
                            > (signed_word)BL_LIMIT) {
                /* Punt, since anything else risks unreasonable heap growth. */
!               if (0 == GETENV("GC_NO_BLACKLIST_WARNING")) {
!                 WARN("Needed to allocate blacklisted block at 0x%lx\n",
!                      (word)hbp);
                }
                size_avail = orig_avail;
--- 665,675 ----
                            > (signed_word)BL_LIMIT) {
                /* Punt, since anything else risks unreasonable heap growth. */
!               if (++GC_large_alloc_warn_suppressed
!                   >= GC_large_alloc_warn_interval) {
!                 WARN("Repeated allocation of very large block "
!                      "(appr. size %ld):\n"
!                      "\tMay lead to memory leak and poor performance.\n",
!                      size_needed);
!                 GC_large_alloc_warn_suppressed = 0;
                }
                size_avail = orig_avail;

Index: alloc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/alloc.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** alloc.c     8 Apr 2002 23:36:49 -0000       1.2
--- alloc.c     6 Feb 2003 01:35:45 -0000       1.3
***************
*** 181,185 ****
      /* is playing by the rules.                                               
*/
      result = (signed_word)GC_words_allocd
!            - (signed_word)GC_mem_freed - expl_managed;
      if (result > (signed_word)GC_words_allocd) {
          result = GC_words_allocd;
--- 181,186 ----
      /* is playing by the rules.                                               
*/
      result = (signed_word)GC_words_allocd
!            - (signed_word)GC_mem_freed 
!            + (signed_word)GC_finalizer_mem_freed - expl_managed;
      if (result > (signed_word)GC_words_allocd) {
          result = GC_words_allocd;
***************
*** 249,253 ****
      if (GC_should_collect()) {
          if (!GC_incremental) {
-           GC_notify_full_gc();
              GC_gcollect_inner();
              n_partial_gcs = 0;
--- 250,253 ----
***************
*** 301,308 ****
--- 301,313 ----
   * Stop the world garbage collection.  Assumes lock held, signals disabled.
   * If stop_func is not GC_never_stop_func, then abort if stop_func returns 
TRUE.
+  * Return TRUE if we successfully completed the collection.
   */
  GC_bool GC_try_to_collect_inner(stop_func)
  GC_stop_func stop_func;
  {
+ #   ifdef CONDPRINT
+         CLOCK_TYPE start_time, current_time;
+ #   endif
+     if (GC_dont_gc) return FALSE;
      if (GC_incremental && GC_collection_in_progress()) {
  #   ifdef CONDPRINT
***************
*** 318,323 ****
--- 323,330 ----
        }
      }
+     if (stop_func == GC_never_stop_func) GC_notify_full_gc();
  #   ifdef CONDPRINT
        if (GC_print_stats) {
+         if (GC_print_stats) GET_TIME(start_time);
        GC_printf2(
           "Initiating full world-stop collection %lu after %ld allocd bytes\n",
***************
*** 358,361 ****
--- 365,375 ----
      }
      GC_finish_collection();
+ #   if defined(CONDPRINT)
+       if (GC_print_stats) {
+         GET_TIME(current_time);
+         GC_printf1("Complete collection took %lu msecs\n",
+                    MS_TIME_DIFF(current_time,start_time));
+       }
+ #   endif
      return(TRUE);
  }
***************
*** 385,388 ****
--- 399,403 ----
      register int i;
      
+     if (GC_dont_gc) return;
      if (GC_incremental && GC_collection_in_progress()) {
        for (i = GC_deficit; i < GC_RATE*n; i++) {
***************
*** 427,430 ****
--- 442,446 ----
      UNLOCK();
      ENABLE_SIGNALS();
+     if (!result && GC_debugging_started) GC_print_all_smashed();
      return(result);
  }
***************
*** 445,449 ****
  #   endif
        
-     STOP_WORLD();
  #   ifdef PRINTTIMES
        GET_TIME(start_time);
--- 461,464 ----
***************
*** 452,455 ****
--- 467,474 ----
        if (GC_print_stats) GET_TIME(start_time);
  #   endif
+ #   if defined(REGISTER_LIBRARIES_EARLY)
+         GC_cond_register_dynamic_libraries();
+ #   endif
+     STOP_WORLD();
  #   ifdef CONDPRINT
        if (GC_print_stats) {
***************
*** 515,518 ****
--- 534,538 ----
          }
      
+     START_WORLD();
  #   ifdef PRINTTIMES
        GET_TIME(current_time);
***************
*** 528,532 ****
  #     endif
  #   endif
-     START_WORLD();
      return(TRUE);
  }
--- 548,551 ----
***************
*** 605,608 ****
--- 624,628 ----
        }
  #   endif
+     COND_DUMP;
      if (GC_find_leak) {
        /* Mark all objects on the free list.  All objects should be */
***************
*** 701,704 ****
--- 721,725 ----
        GC_words_wasted = 0;
        GC_mem_freed = 0;
+       GC_finalizer_mem_freed = 0;
        
  #   ifdef USE_MUNMAP
***************
*** 724,727 ****
--- 745,749 ----
      DCL_LOCK_STATE;
      
+     if (GC_debugging_started) GC_print_all_smashed();
      GC_INVOKE_FINALIZERS();
      DISABLE_SIGNALS();
***************
*** 735,739 ****
      UNLOCK();
      ENABLE_SIGNALS();
!     if(result) GC_INVOKE_FINALIZERS();
      return(result);
  }
--- 757,764 ----
      UNLOCK();
      ENABLE_SIGNALS();
!     if(result) {
!         if (GC_debugging_started) GC_print_all_smashed();
!         GC_INVOKE_FINALIZERS();
!     }
      return(result);
  }
***************
*** 741,746 ****
  void GC_gcollect GC_PROTO(())
  {
-     GC_notify_full_gc();
      (void)GC_try_to_collect(GC_never_stop_func);
  }
  
--- 766,771 ----
  void GC_gcollect GC_PROTO(())
  {
      (void)GC_try_to_collect(GC_never_stop_func);
+     if (GC_have_errors) GC_print_all_errors();
  }
  
***************
*** 944,948 ****
      if (!GC_incremental && !GC_dont_gc &&
        (GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) {
-       GC_notify_full_gc();
        GC_gcollect_inner();
      } else {
--- 969,972 ----
***************
*** 969,973 ****
                if (GC_fail_count++ < GC_max_retries) {
                    WARN("Out of Memory!  Trying to continue ...\n", 0);
-           GC_notify_full_gc();
            GC_gcollect_inner();
        } else {
--- 993,996 ----
***************
*** 1007,1011 ****
        ENTER_GC();
        /* Do our share of marking work */
!         if(TRUE_INCREMENTAL && !GC_dont_gc) GC_collect_a_little_inner(1);
        /* Sweep blocks for objects of this size */
          GC_continue_reclaim(sz, kind);
--- 1030,1034 ----
        ENTER_GC();
        /* Do our share of marking work */
!         if(TRUE_INCREMENTAL) GC_collect_a_little_inner(1);
        /* Sweep blocks for objects of this size */
          GC_continue_reclaim(sz, kind);

Index: alpha_mach_dep.S
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/alpha_mach_dep.S,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2

Index: backgraph.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/backgraph.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** backgraph.c 8 Apr 2002 23:36:49 -0000       1.1
--- backgraph.c 6 Feb 2003 01:35:45 -0000       1.2
***************
*** 308,311 ****
--- 308,312 ----
    while (currentp < (word *)(p + gc_descr)) {
      word current = *currentp++;
+     FIXUP_POINTER(current);
      if (current >= (word)GC_least_plausible_heap_addr && 
        current <= (word)GC_greatest_plausible_heap_addr) {

Index: config.guess
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/config.guess,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** config.guess        8 Apr 2002 23:36:49 -0000       1.2
--- config.guess        6 Feb 2003 01:35:45 -0000       1.3
***************
*** 1,8 ****
  #! /bin/sh
  # Attempt to guess a canonical system name.
! #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
! #   Free Software Foundation, Inc.
  
! timestamp='2001-09-04'
  
  # This file is free software; you can redistribute it and/or modify it
--- 1,8 ----
  #! /bin/sh
  # Attempt to guess a canonical system name.
! #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
! #   2000, 2001, 2002 Free Software Foundation, Inc.
  
! timestamp='2002-03-20'
  
  # This file is free software; you can redistribute it and/or modify it
***************
*** 25,30 ****
  # the same distribution terms that you use for the rest of that program.
  
! # Written by Per Bothner <address@hidden>.
! # Please send patches to <address@hidden>.
  #
  # This script attempts to guess a canonical system name similar to
--- 25,31 ----
  # the same distribution terms that you use for the rest of that program.
  
! # Originally written by Per Bothner <address@hidden>.
! # Please send patches to <address@hidden>.  Submit a context
! # diff and a properly formatted ChangeLog entry.
  #
  # This script attempts to guess a canonical system name similar to
***************
*** 98,102 ****
  set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
   ,,)    echo "int dummy(){}" > $dummy.c ;
!       for c in cc gcc c89 ; do
          ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
          if test $? = 0 ; then
--- 99,103 ----
  set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
   ,,)    echo "int dummy(){}" > $dummy.c ;
!       for c in cc gcc c89 c99 ; do
          ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
          if test $? = 0 ; then
***************
*** 128,132 ****
  case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
      *:NetBSD:*:*)
!       # Netbsd (nbsd) targets should (where applicable) match one or
        # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
        # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
--- 129,133 ----
  case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
      *:NetBSD:*:*)
!       # NetBSD (nbsd) targets should (where applicable) match one or
        # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
        # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
***************
*** 135,154 ****
        # compatibility and a consistent mechanism for selecting the
        # object file format.
!       # Determine the machine/vendor (is the vendor relevant).
!       case "${UNAME_MACHINE}" in
!           amiga) machine=m68k-unknown ;;
!           arm32) machine=arm-unknown ;;
!           atari*) machine=m68k-atari ;;
!           sun3*) machine=m68k-sun ;;
!           mac68k) machine=m68k-apple ;;
!           macppc) machine=powerpc-apple ;;
!           hp3[0-9][05]) machine=m68k-hp ;;
!           ibmrt|romp-ibm) machine=romp-ibm ;;
!           *) machine=${UNAME_MACHINE}-unknown ;;
        esac
        # The Operating System including object format, if it has switched
        # to ELF recently, or will in the future.
!       case "${UNAME_MACHINE}" in
!           
i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
                eval $set_cc_for_build
                if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
--- 136,155 ----
        # compatibility and a consistent mechanism for selecting the
        # object file format.
!       #
!       # Note: NetBSD doesn't particularly care about the vendor
!       # portion of the name.  We always set it to "unknown".
!       sysctl="sysctl -n hw.machine_arch"
!       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
!           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
!       case "${UNAME_MACHINE_ARCH}" in
!           arm*) machine=arm-unknown ;;
!           sh3el) machine=shl-unknown ;;
!           sh3eb) machine=sh-unknown ;;
!           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
        esac
        # The Operating System including object format, if it has switched
        # to ELF recently, or will in the future.
!       case "${UNAME_MACHINE_ARCH}" in
!           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
                eval $set_cc_for_build
                if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
***************
*** 173,176 ****
--- 174,216 ----
        echo "${machine}-${os}${release}"
        exit 0 ;;
+     amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+     *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
      alpha:OSF1:*:*)
        if test $UNAME_RELEASE = "V4.0"; then
***************
*** 248,274 ****
        echo m68k-unknown-sysv4
        exit 0;;
-     amiga:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
      *:[Aa]miga[Oo][Ss]:*:*)
        echo ${UNAME_MACHINE}-unknown-amigaos
        exit 0 ;;
!     arc64:OpenBSD:*:*)
!       echo mips64el-unknown-openbsd${UNAME_RELEASE}
!       exit 0 ;;
!     arc:OpenBSD:*:*)
!       echo mipsel-unknown-openbsd${UNAME_RELEASE}
!       exit 0 ;;
!     hkmips:OpenBSD:*:*)
!       echo mips-unknown-openbsd${UNAME_RELEASE}
!       exit 0 ;;
!     pmax:OpenBSD:*:*)
!       echo mipsel-unknown-openbsd${UNAME_RELEASE}
!       exit 0 ;;
!     sgi:OpenBSD:*:*)
!       echo mips-unknown-openbsd${UNAME_RELEASE}
!       exit 0 ;;
!     wgrisc:OpenBSD:*:*)
!       echo mipsel-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
      *:OS/390:*:*)
--- 288,296 ----
        echo m68k-unknown-sysv4
        exit 0;;
      *:[Aa]miga[Oo][Ss]:*:*)
        echo ${UNAME_MACHINE}-unknown-amigaos
        exit 0 ;;
!     *:[Mm]orph[Oo][Ss]:*:*)
!       echo ${UNAME_MACHINE}-unknown-morphos
        exit 0 ;;
      *:OS/390:*:*)
***************
*** 320,324 ****
        exit 0 ;;
      sun*:*:4.2BSD:*)
!       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 
2>/dev/null`
        test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
        case "`/bin/arch`" in
--- 342,346 ----
        exit 0 ;;
      sun*:*:4.2BSD:*)
!       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 
2>/dev/null`
        test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
        case "`/bin/arch`" in
***************
*** 334,343 ****
        echo sparc-auspex-sunos${UNAME_RELEASE}
        exit 0 ;;
-     sparc*:NetBSD:*)
-       echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
-       exit 0 ;;
-     atari*:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
      # The situation for MiNT is a little confusing.  The machine name
      # can be virtually everything (everything which is not
--- 356,359 ----
***************
*** 366,381 ****
          echo m68k-unknown-mint${UNAME_RELEASE}
          exit 0 ;;
-     sun3*:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-     mac68k:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-     mvme68k:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-     mvme88k:OpenBSD:*:*)
-       echo m88k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
      powerpc:machten:*:*)
        echo powerpc-apple-machten${UNAME_RELEASE}
--- 382,385 ----
***************
*** 507,511 ****
        exit 0 ;;
      *:AIX:*:[45])
!       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | 
awk '{ print $1 }'`
        if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; 
then
                IBM_ARCH=rs6000
--- 511,515 ----
        exit 0 ;;
      *:AIX:*:[45])
!       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk 
'{ print $1 }'`
        if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; 
then
                IBM_ARCH=rs6000
***************
*** 547,554 ****
            9000/[34]?? )         HP_ARCH=m68k ;;
            9000/[678][0-9][0-9])
!               case "${HPUX_REV}" in
!                 11.[0-9][0-9])
!                   if [ -x /usr/bin/getconf ]; then
!                     sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 
2>/dev/null`
                      sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 
2>/dev/null`
                      case "${sc_cpu_version}" in
--- 551,556 ----
            9000/[34]?? )         HP_ARCH=m68k ;;
            9000/[678][0-9][0-9])
!               if [ -x /usr/bin/getconf ]; then
!                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
                      sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 
2>/dev/null`
                      case "${sc_cpu_version}" in
***************
*** 559,569 ****
                            32) HP_ARCH="hppa2.0n" ;;
                            64) HP_ARCH="hppa2.0w" ;;
                          esac ;;
                      esac
!                   fi ;;
!               esac
!               if [ "${HP_ARCH}" = "" ]; then
!             eval $set_cc_for_build
!               sed 's/^              //' << EOF >$dummy.c
  
                #define _HPUX_SOURCE
--- 561,571 ----
                            32) HP_ARCH="hppa2.0n" ;;
                            64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
                          esac ;;
                      esac
!               fi
!               if [ "${HP_ARCH}" = "" ]; then
!                   eval $set_cc_for_build
!                   sed 's/^              //' << EOF >$dummy.c
  
                #define _HPUX_SOURCE
***************
*** 598,605 ****
                }
  EOF
!           (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && 
HP_ARCH=`./$dummy`
!           if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
!           rm -f $dummy.c $dummy
!       fi ;;
        esac
        echo ${HP_ARCH}-hp-hpux${HPUX_REV}
--- 600,607 ----
                }
  EOF
!                   (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && 
HP_ARCH=`./$dummy`
!                   if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
!                   rm -f $dummy.c $dummy
!               fi ;;
        esac
        echo ${HP_ARCH}-hp-hpux${HPUX_REV}
***************
*** 665,671 ****
        echo hppa1.1-hp-lites
        exit 0 ;;
-     hppa*:OpenBSD:*:*)
-       echo hppa-unknown-openbsd
-       exit 0 ;;
      C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
        echo c1-convex-bsd
--- 667,670 ----
***************
*** 686,692 ****
        echo c4-convex-bsd
          exit 0 ;;
-     CRAY*X-MP:*:*:*)
-       echo xmp-cray-unicos
-         exit 0 ;;
      CRAY*Y-MP:*:*:*)
        echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
--- 685,688 ----
***************
*** 710,716 ****
        echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
        exit 0 ;;
-     CRAY-2:*:*:*)
-       echo cray2-cray-unicos
-         exit 0 ;;
      F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
        FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 
'abcdefghijklmnopqrstuvwxyz'`
--- 706,709 ----
***************
*** 719,725 ****
          echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
          exit 0 ;;
-     hp300:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
      i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
        echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
--- 712,715 ----
***************
*** 734,740 ****
        echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 
's/[-(].*//'`
        exit 0 ;;
-     *:OpenBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 
's/[-_].*/\./'`
-       exit 0 ;;
      i*:CYGWIN*:*)
        echo ${UNAME_MACHINE}-pc-cygwin
--- 724,727 ----
***************
*** 746,749 ****
--- 733,739 ----
        echo ${UNAME_MACHINE}-pc-pw32
        exit 0 ;;
+     x86:Interix*:3*)
+       echo i386-pc-interix3
+       exit 0 ;;
      i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
        # How do we know it's Interix rather than the generic POSIX subsystem?
***************
*** 771,775 ****
        exit 0 ;;
      ia64:Linux:*:*)
!       echo ${UNAME_MACHINE}-unknown-linux
        exit 0 ;;
      m68*:Linux:*:*)
--- 761,765 ----
        exit 0 ;;
      ia64:Linux:*:*)
!       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit 0 ;;
      m68*:Linux:*:*)
***************
*** 777,784 ****
        exit 0 ;;
      mips:Linux:*:*)
!       case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
!         big)    echo mips-unknown-linux-gnu && exit 0 ;;
!         little) echo mipsel-unknown-linux-gnu && exit 0 ;;
!       esac
        ;;
      ppc:Linux:*:*)
--- 767,788 ----
        exit 0 ;;
      mips:Linux:*:*)
!       eval $set_cc_for_build
!       sed 's/^        //' << EOF >$dummy.c
!       #undef CPU
!       #undef mips
!       #undef mipsel
!       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || 
defined(MIPSEL)
!       CPU=mipsel
!       #else
!       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || 
defined(MIPSEB)
!       CPU=mips
!       #else
!       CPU=
!       #endif
!       #endif
! EOF
!       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
!       rm -f $dummy.c
!       test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
        ;;
      ppc:Linux:*:*)
***************
*** 829,833 ****
        # first see if it will tell us. cd to the root directory to prevent
        # problems with other programs or directories called `ld' in the path.
!       ld_supported_targets=`cd /; ld --help 2>&1 \
                         | sed -ne '/supported targets:/!d
                                    s/[         ][      ]*/ /g
--- 833,838 ----
        # first see if it will tell us. cd to the root directory to prevent
        # problems with other programs or directories called `ld' in the path.
!       # Set LC_ALL=C to ensure ld outputs messages in English.
!       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
                         | sed -ne '/supported targets:/!d
                                    s/[         ][      ]*/ /g
***************
*** 853,882 ****
        # Determine whether the default compiler is a.out or elf
        eval $set_cc_for_build
!       cat >$dummy.c <<EOF
! #include <features.h>
! #ifdef __cplusplus
! #include <stdio.h>  /* for printf() prototype */
!       int main (int argc, char *argv[]) {
! #else
!       int main (argc, argv) int argc; char *argv[]; {
! #endif
! #ifdef __ELF__
! # ifdef __GLIBC__
! #  if __GLIBC__ >= 2
!     printf ("%s-pc-linux-gnu\n", argv[1]);
! #  else
!     printf ("%s-pc-linux-gnulibc1\n", argv[1]);
! #  endif
! # else
!    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
! # endif
! #else
!   printf ("%s-pc-linux-gnuaout\n", argv[1]);
! #endif
!   return 0;
! }
  EOF
!       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy 
"${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
!       rm -f $dummy.c $dummy
        test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
        ;;
--- 858,884 ----
        # Determine whether the default compiler is a.out or elf
        eval $set_cc_for_build
!       sed 's/^        //' << EOF >$dummy.c
!       #include <features.h>
!       #ifdef __ELF__
!       # ifdef __GLIBC__
!       #  if __GLIBC__ >= 2
!       LIBC=gnu
!       #  else
!       LIBC=gnulibc1
!       #  endif
!       # else
!       LIBC=gnulibc1
!       # endif
!       #else
!       #ifdef __INTEL_COMPILER
!       LIBC=gnu
!       #else
!       LIBC=gnuaout
!       #endif
!       #endif
  EOF
!       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
!       rm -f $dummy.c
!       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && 
exit 0
        test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
        ;;
***************
*** 957,961 ****
      M68*:*:R3V[567]*:*)
        test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
!     3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 
4850:*:4.0:3.0)
        OS_REL=''
        test -r /etc/.relid \
--- 959,963 ----
      M68*:*:R3V[567]*:*)
        test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
!     3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 
3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
        OS_REL=''
        test -r /etc/.relid \
***************
*** 1058,1070 ****
        exit 0 ;;
      *:procnto*:*:* | *:QNX:[0123456789]*:*)
!       if test "${UNAME_MACHINE}" = "x86pc"; then
                UNAME_MACHINE=pc
        fi
!       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
        exit 0 ;;
      *:QNX:*:4*)
        echo i386-pc-qnx
        exit 0 ;;
!     NSR-[KW]:NONSTOP_KERNEL:*:*)
        echo nsr-tandem-nsk${UNAME_RELEASE}
        exit 0 ;;
--- 1060,1074 ----
        exit 0 ;;
      *:procnto*:*:* | *:QNX:[0123456789]*:*)
!       UNAME_PROCESSOR=`uname -p`
!       if test "$UNAME_PROCESSOR" = "x86"; then
!               UNAME_PROCESSOR=i386
                UNAME_MACHINE=pc
        fi
!       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
        exit 0 ;;
      *:QNX:*:4*)
        echo i386-pc-qnx
        exit 0 ;;
!     NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
        echo nsr-tandem-nsk${UNAME_RELEASE}
        exit 0 ;;

Index: config.sub
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/config.sub,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** config.sub  8 Apr 2002 23:36:49 -0000       1.2
--- config.sub  6 Feb 2003 01:35:45 -0000       1.3
***************
*** 1,8 ****
  #! /bin/sh
  # Configuration validation subroutine script.
! #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
! #   Free Software Foundation, Inc.
  
! timestamp='2001-09-07'
  
  # This file is (in principle) common to ALL GNU software.
--- 1,8 ----
  #! /bin/sh
  # Configuration validation subroutine script.
! #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
! #   2000, 2001, 2002 Free Software Foundation, Inc.
  
! timestamp='2002-03-07'
  
  # This file is (in principle) common to ALL GNU software.
***************
*** 30,34 ****
  # the same distribution terms that you use for the rest of that program.
  
! # Please send patches to <address@hidden>.
  #
  # Configuration subroutine to validate and canonicalize a configuration type.
--- 30,35 ----
  # the same distribution terms that you use for the rest of that program.
  
! # Please send patches to <address@hidden>.  Submit a context
! # diff and a properly formatted ChangeLog entry.
  #
  # Configuration subroutine to validate and canonicalize a configuration type.
***************
*** 118,122 ****
  maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
  case $maybe_os in
!   nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
      os=-$maybe_os
      basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
--- 119,123 ----
  maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
  case $maybe_os in
!   nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
      os=-$maybe_os
      basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
***************
*** 227,230 ****
--- 228,232 ----
        | a29k \
        | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | 
alpha64pca5[67] \
        | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
        | c4x | clipper \
***************
*** 234,256 ****
        | i370 | i860 | i960 | ia64 \
        | m32r | m68000 | m68k | m88k | mcore \
!       | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
        | mips64vr4100 | mips64vr4100el | mips64vr4300 \
        | mips64vr4300el | mips64vr5000 | mips64vr5000el \
        | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
!       | mipsisa32 \
        | mn10200 | mn10300 \
        | ns16k | ns32k \
!       | openrisc \
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
        | pyramid \
!       | s390 | s390x \
!       | sh | sh[34] | sh[34]eb | shbe | shle \
!       | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
!       | stormy16 | strongarm \
        | tahoe | thumb | tic80 | tron \
!       | v850 \
        | we32k \
!       | x86 | xscale \
        | z8k)
                basic_machine=$basic_machine-unknown
--- 236,257 ----
        | i370 | i860 | i960 | ia64 \
        | m32r | m68000 | m68k | m88k | mcore \
!       | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
        | mips64vr4100 | mips64vr4100el | mips64vr4300 \
        | mips64vr4300el | mips64vr5000 | mips64vr5000el \
        | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
!       | mipsisa32 | mipsisa64 \
        | mn10200 | mn10300 \
        | ns16k | ns32k \
!       | openrisc | or32 \
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
        | pyramid \
!       | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
!       | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | 
sparcv9b \
!       | strongarm \
        | tahoe | thumb | tic80 | tron \
!       | v850 | v850e \
        | we32k \
!       | x86 | xscale | xstormy16 | xtensa \
        | z8k)
                basic_machine=$basic_machine-unknown
***************
*** 279,287 ****
        | a29k-* \
        | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
!       | alphapca5[67]-* | arc-* \
        | arm-*  | armbe-* | armle-* | armv*-* \
        | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c54x-* \
!       | clipper-* | cray2-* | cydra-* \
        | d10v-* | d30v-* \
        | elxsi-* \
--- 280,290 ----
        | a29k-* \
        | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
!       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
!       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
        | arm-*  | armbe-* | armle-* | armv*-* \
+       | avr-* \
        | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c54x-* \
!       | clipper-* | cydra-* \
        | d10v-* | d30v-* \
        | elxsi-* \
***************
*** 291,295 ****
        | i*86-* | i860-* | i960-* | ia64-* \
        | m32r-* \
!       | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
        | m88110-* | m88k-* | mcore-* \
        | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
--- 294,298 ----
        | i*86-* | i860-* | i960-* | ia64-* \
        | m32r-* \
!       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
        | m88110-* | m88k-* | mcore-* \
        | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
***************
*** 303,314 ****
        | pyramid-* \
        | romp-* | rs6000-* \
!       | s390-* | s390x-* \
!       | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
!       | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
!       | sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
!       | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
!       | v850-* | vax-* \
        | we32k-* \
!       | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
        | ymp-* \
        | z8k-*)
--- 306,317 ----
        | pyramid-* \
        | romp-* | rs6000-* \
!       | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
!       | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
!       | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
!       | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
!       | v850-* | v850e-* | vax-* \
        | we32k-* \
!       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
!       | xtensa-* \
        | ymp-* \
        | z8k-*)
***************
*** 375,378 ****
--- 378,385 ----
                os=-dynix
                ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
        convex-c1)
                basic_machine=c1-convex
***************
*** 395,408 ****
                os=-bsd
                ;;
!       cray | ymp)
!               basic_machine=ymp-cray
!               os=-unicos
!               ;;
!       cray2)
!               basic_machine=cray2-cray
!               os=-unicos
!               ;;
!       [cjt]90)
!               basic_machine=${basic_machine}-cray
                os=-unicos
                ;;
--- 402,407 ----
                os=-bsd
                ;;
!       cray | j90)
!               basic_machine=j90-cray
                os=-unicos
                ;;
***************
*** 419,422 ****
--- 418,429 ----
                basic_machine=mips-dec
                ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
        delta | 3300 | motorola-3300 | motorola-delta \
              | 3300-motorola | delta-motorola)
***************
*** 599,610 ****
                os=-mint
                ;;
-       mipsel*-linux*)
-               basic_machine=mipsel-unknown
-               os=-linux-gnu
-               ;;
-       mips*-linux*)
-               basic_machine=mips-unknown
-               os=-linux-gnu
-               ;;
        mips3*-*)
                basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
--- 606,609 ----
***************
*** 621,624 ****
--- 620,627 ----
                os=-coff
                ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
        msdos)
                basic_machine=i386-pc
***************
*** 700,703 ****
--- 703,710 ----
                os=-proelf
                ;;
+       or32 | or32-*)
+               basic_machine=or32-unknown
+               os=-coff
+               ;;
        OSE68000 | ose68000)
                basic_machine=m68000-ericsson
***************
*** 725,729 ****
                basic_machine=ns32k-pc532
                ;;
!       pentium | p5 | k5 | k6 | nexgen)
                basic_machine=i586-pc
                ;;
--- 732,736 ----
                basic_machine=ns32k-pc532
                ;;
!       pentium | p5 | k5 | k6 | nexgen | viac3)
                basic_machine=i586-pc
                ;;
***************
*** 734,738 ****
                basic_machine=i686-pc
                ;;
!       pentium-* | p5-* | k5-* | k6-* | nexgen-*)
                basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
                ;;
--- 741,745 ----
                basic_machine=i686-pc
                ;;
!       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
                basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
                ;;
***************
*** 785,788 ****
--- 792,801 ----
                basic_machine=romp-ibm
                ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
        sa29200)
                basic_machine=a29k-amd
***************
*** 796,800 ****
                os=-hms
                ;;
!       sparclite-wrs)
                basic_machine=sparclite-wrs
                os=-vxworks
--- 809,813 ----
                os=-hms
                ;;
!       sparclite-wrs | simso-wrs)
                basic_machine=sparclite-wrs
                os=-vxworks
***************
*** 854,858 ****
                basic_machine=i386-sun
                ;;
!       sv1)
                basic_machine=sv1-cray
                os=-unicos
--- 867,871 ----
                basic_machine=i386-sun
                ;;
!         sv1)
                basic_machine=sv1-cray
                os=-unicos
***************
*** 862,867 ****
                os=-dynix
                ;;
        t3e)
!               basic_machine=t3e-cray
                os=-unicos
                ;;
--- 875,888 ----
                os=-dynix
                ;;
+       t3d)
+               basic_machine=alpha-cray
+               os=-unicos
+               ;;
        t3e)
!               basic_machine=alphaev5-cray
!               os=-unicos
!               ;;
!       t90)
!               basic_machine=t90-cray
                os=-unicos
                ;;
***************
*** 876,879 ****
--- 897,904 ----
                basic_machine=mipstx39el-unknown
                ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
        tower | tower-32)
                basic_machine=m68k-ncr
***************
*** 926,936 ****
                os=-windows32-msvcrt
                ;;
-       xmp)
-               basic_machine=xmp-cray
-               os=-unicos
-               ;;
          xps | xps100)
                basic_machine=xps100-honeywell
                ;;
        z8k-*-coff)
                basic_machine=z8k-unknown
--- 951,961 ----
                os=-windows32-msvcrt
                ;;
          xps | xps100)
                basic_machine=xps100-honeywell
                ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
        z8k-*-coff)
                basic_machine=z8k-unknown
***************
*** 953,963 ****
                basic_machine=hppa1.1-oki
                ;;
-       mips)
-               if [ x$os = x-linux-gnu ]; then
-                       basic_machine=mips-unknown
-               else
-                       basic_machine=mips-mips
-               fi
-               ;;
        romp)
                basic_machine=romp-ibm
--- 978,981 ----
***************
*** 982,985 ****
--- 1000,1006 ----
                basic_machine=sh-unknown
                ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
        sparc | sparcv9 | sparcv9b)
                basic_machine=sparc-sun
***************
*** 1069,1073 ****
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
!             | -os2* | -vos*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
--- 1090,1095 ----
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
!             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
!             | -morphos* | -superux* | -rtmk* | -rtmk-nova*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
***************
*** 1121,1124 ****
--- 1143,1149 ----
                os=-aos
                ;;
+       -atheos*)
+               os=-atheos
+               ;;
        -386bsd)
                os=-bsd
***************
*** 1127,1130 ****
--- 1152,1158 ----
                os=-sysv
                ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
        -ns2 )
                os=-nextstep2
***************
*** 1201,1204 ****
--- 1229,1233 ----
                os=-aout
                ;;
+       # This must come before the *-dec entry.
        pdp10-*)
                os=-tops20
***************
*** 1230,1233 ****
--- 1259,1265 ----
        mips*-*)
                os=-elf
+               ;;
+       or32-*)
+               os=-coff
                ;;
        *-tti)  # must be before sparc entry or we get the wrong os.

Index: configure
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/configure,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** configure   8 Apr 2002 23:36:49 -0000       1.2
--- configure   6 Feb 2003 01:35:45 -0000       1.3
***************
*** 1,35 ****
  #! /bin/sh
- 
  # Guess values for system-dependent variables and create Makefiles.
! # Generated automatically using autoconf version 2.13 
! # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
  #
  # This configure script is free software; the Free Software Foundation
  # gives unlimited permission to copy, distribute and modify it.
  
- # Defaults:
[...9359 lines suppressed...]
! ac_clean_files=$ac_clean_files_save
! 
! # configure is writing to config.log, and then calls config.status.
! # config.status does its own redirection, appending to config.log.
! # Unfortunately, on DOS this fails, as config.log is still kept open
! # by configure, so config.status won't be able to write to it; its
! # output is simply discarded.  So we exec the FD to /dev/null,
! # effectively closing config.log, so it can be properly (re)opened and
! # appended to by config.status.  When coming back to configure, we
! # need to make the FD available again.
! if test "$no_create" != yes; then
!   ac_cs_success=:
!   exec 5>/dev/null
!   $SHELL $CONFIG_STATUS || ac_cs_success=false
!   exec 5>>config.log
!   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
!   # would make configure fail if this is the last instruction.
!   $ac_cs_success || { (exit 1); exit 1; }
! fi
  

Index: configure.host
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/configure.host,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** configure.host      14 May 2002 10:15:27 -0000      1.2
--- configure.host      6 Feb 2003 01:35:45 -0000       1.3
***************
*** 25,32 ****
      gc_cflags=-fexceptions
      ;;
! ## - commented out by Rhys Weatherley as it caused problems for hpux users.
! ##    *-*-hpux* )
! ##    gc_cflags=+ESdbgasm
! ##    ;;
  esac
  
--- 25,31 ----
      gc_cflags=-fexceptions
      ;;
!     *-*-hpux* )
!     gc_cflags=+ESdbgasm
!     ;;
  esac
  

Index: configure.in
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/configure.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** configure.in        8 Apr 2002 23:36:49 -0000       1.2
--- configure.in        6 Feb 2003 01:35:45 -0000       1.3
***************
*** 14,25 ****
  dnl Process this file with autoconf to produce configure.
  
! AC_INIT(gcj_mlc.c)
  
  dnl Can't be done in GC_CONFIGURE because that confuses automake. 
! AC_CONFIG_AUX_DIR(.)
  
! AC_CANONICAL_SYSTEM
  
! GC_CONFIGURE(.)
  
  AC_ARG_ENABLE(threads, [  --enable-threads=TYPE   choose threading package],
--- 14,69 ----
  dnl Process this file with autoconf to produce configure.
  
! AC_INIT(gc, 6.1, address@hidden)
! 
! AM_INIT_AUTOMAKE(gc, 6.1, no-define)
! 
! AC_CONFIG_SRCDIR(gcj_mlc.c)
  
  dnl Can't be done in GC_CONFIGURE because that confuses automake. 
! dnl AC_CONFIG_AUX_DIR(.)
! 
! AC_CANONICAL_HOST
! 
! AC_PROG_CC
! AC_PROG_CXX
! 
! AM_PROG_AS
! AC_CHECK_TOOL(AR, ar)
! AC_CHECK_TOOL(RANLIB, ranlib, :)
! 
! AC_PROG_INSTALL
! 
! AM_MAINTAINER_MODE
! 
! if test "[$]{srcdir}" = "."; then
!   if test "[$]{with_target_subdir}" != "." -a -n "[$]{with_target_subdir}"; 
then
!     gc_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1"
!   else
!     gc_basedir="[$]{srcdir}/[$]{with_multisrctop}$1"
!   fi
! else
!   gc_basedir="[$]{srcdir}/$1"
! fi
! AC_SUBST(gc_basedir)
! 
! # We need AC_EXEEXT to keep automake happy in cygnus mode.  However,
! # at least currently, we never actually build a program, so we never
! # need to use $(EXEEXT).  Moreover, the test for EXEEXT normally
! # fails, because we are probably configuring with a cross compiler
! # which can't create executables.  So we include AC_EXEEXT to keep
! # automake happy, but we don't execute it, since we don't care about
! # the result.
! if false; then
!   # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
!   # to nothing, so nothing would remain between `then' and `fi' if it
!   # were not for the `:' below.
!   :
!   AC_EXEEXT
! fi
  
! . [$]{srcdir}/configure.host
  
! GC_CFLAGS=${gc_cflags}
! AC_SUBST(GC_CFLAGS)
  
  AC_ARG_ENABLE(threads, [  --enable-threads=TYPE   choose threading package],
***************
*** 41,44 ****
--- 85,92 ----
  )
  
+ AC_ARG_ENABLE(cplusplus,
+ [  --enable-cplusplus         include C++ support in GC library and include 
directory],
+ )
+ 
  INCLUDES=-I${srcdir}/include
  THREADLIBS=
***************
*** 51,58 ****
      THREADLIBS=-lpthread
      case "$host" in
!      x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux*)
        AC_DEFINE(GC_LINUX_THREADS)
        AC_DEFINE(_REENTRANT)
!         if test "${enable_parallel_mark}"; then
          AC_DEFINE(PARALLEL_MARK)
        fi
--- 99,106 ----
      THREADLIBS=-lpthread
      case "$host" in
!      x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | 
x86_64-*-linux* | alpha-*-linux*)
        AC_DEFINE(GC_LINUX_THREADS)
        AC_DEFINE(_REENTRANT)
!         if test "${enable_parallel_mark}" = yes; then
          AC_DEFINE(PARALLEL_MARK)
        fi
***************
*** 86,93 ****
--- 134,157 ----
        AC_DEFINE(GC_IRIX_THREADS)
        ;;
+      *-*-cygwin*)
+       AC_DEFINE(GC_WIN32_THREADS)
+       ;;
+      *-*-osf*)
+       AC_DEFINE(GC_OSF1_THREADS)
+         if test "${enable_parallel_mark}" = yes; then
+         AC_DEFINE(PARALLEL_MARK)
+         AC_DEFINE(THREAD_LOCAL_ALLOC)
+         # May want to enable it in other cases, too.
+         # Measurements havent yet been done.
+       fi
+       INCLUDES="$INCLUDES -pthread"
+       THREADLIBS="-lpthread -lrt"
+       ;;
      esac
      ;;
   win32)
      AC_DEFINE(GC_WIN32_THREADS)
+     dnl Wine getenv may not return NULL for missing entry
+     AC_DEFINE(NO_GETENV)
      ;;
   dgux386)
***************
*** 95,99 ****
      # Use pthread GCC  switch
      THREADLIBS=-pthread
!     if test "${enable_parallel_mark}"; then
          AC_DEFINE(PARALLEL_MARK)
      fi
--- 159,163 ----
      # Use pthread GCC  switch
      THREADLIBS=-pthread
!     if test "${enable_parallel_mark}" = yes; then
          AC_DEFINE(PARALLEL_MARK)
      fi
***************
*** 130,133 ****
--- 194,199 ----
  
  addobjs=
+ addincludes=
+ addtests=
  CXXINCLUDES=
  case "$TARGET_ECOS" in
***************
*** 140,143 ****
--- 206,216 ----
        ;;
  esac
+ 
+ if test "${enable_cplusplus}" = yes; then
+       addobjs="$addobjs gc_cpp.lo"
+       addincludes="$addincludes include/gc_cpp.h include/gc_allocator.h"
+       addtests="$addtests test_cpp"
+ fi
+ 
  AC_SUBST(CXX)
  
***************
*** 146,149 ****
--- 219,232 ----
  
  machdep=
+ 
+ case "$host" in
+  alpha-*-openbsd*)
+      AC_DISABLE_SHARED
+      ;;
+  *)
+      AC_ENABLE_SHARED
+      ;;
+ esac
+ 
  case "$host" in
   alpha-*-openbsd*)
***************
*** 151,158 ****
      if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
         AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is 
disabled)
-        AM_DISABLE_SHARED
      fi
      ;;
!  alpha*-*-*)
      machdep="alpha_mach_dep.lo"
      ;;
--- 234,240 ----
      if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
         AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is 
disabled)
      fi
      ;;
!  alpha*-*-linux*)
      machdep="alpha_mach_dep.lo"
      ;;
***************
*** 170,173 ****
--- 252,257 ----
   mips-nec-sysv*|mips-unknown-sysv*)
      ;;
+  mips*-*-linux*) 
+     ;; 
   mips-*-*)
      machdep="mips_sgi_mach_dep.lo"
***************
*** 193,198 ****
  addobjs="$addobjs $machdep"
  AC_SUBST(addobjs)
  
! AM_PROG_LIBTOOL
  
  dnl checks for AViiON Machines running DGUX
--- 277,284 ----
  addobjs="$addobjs $machdep"
  AC_SUBST(addobjs)
+ AC_SUBST(addincludes)
+ AC_SUBST(addtests)
  
! AC_PROG_LIBTOOL
  
  dnl checks for AViiON Machines running DGUX
***************
*** 203,210 ****
  
  if test $ac_is_dgux = yes; then
!     if test "$enable_full_debug" = "yes"; then
        CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
        CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
!     else
        CFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
        CXXFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
--- 289,296 ----
  
  if test $ac_is_dgux = yes; then
!    if test "$enable_full_debug" = "yes"; then
        CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
        CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
!    else
        CFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
        CXXFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
***************
*** 291,295 ****
        AC_DEFINE(MAKE_BACK_GRAPH)
        ;;
!       x86-*-linux* | i586-*-linux* | i686-*-linux* )
        AC_DEFINE(MAKE_BACK_GRAPH)
        AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
--- 377,381 ----
        AC_DEFINE(MAKE_BACK_GRAPH)
        ;;
!       x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
        AC_DEFINE(MAKE_BACK_GRAPH)
        AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
***************
*** 302,306 ****
--- 388,403 ----
    fi)
  
+ AC_ARG_ENABLE(redirect-malloc,
+ [  --enable-redirect-malloc  redirect malloc and friends to GC routines])
  
+ if test "${enable_redirect_malloc}" = yes; then
+     if test "${enable_full_debug}" = yes; then
+       AC_DEFINE(REDIRECT_MALLOC, GC_debug_malloc_replacement)
+       AC_DEFINE(REDIRECT_REALLOC, GC_debug_realloc_replacement)
+       AC_DEFINE(REDIRECT_FREE, GC_debug_free)
+     else
+       AC_DEFINE(REDIRECT_MALLOC, GC_malloc)
+     fi
+ fi
  
  AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
***************
*** 315,319 ****
  srcdir=${srcdir}
  host=${host}
- target=${target}
  with_multisubdir=${with_multisubdir}
  ac_configure_args="${multilib_arg} ${ac_configure_args}"
--- 412,415 ----

Index: dbg_mlc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/dbg_mlc.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** dbg_mlc.c   8 Apr 2002 23:36:49 -0000       1.2
--- dbg_mlc.c   6 Feb 2003 01:35:45 -0000       1.3
***************
*** 61,65 ****
  
  # if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \
!      || defined(HPUX) || defined(IRIX) || defined(OSF1)
  #   define RANDOM() random()
  # else
--- 61,65 ----
  
  # if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \
!      || defined(HPUX) || defined(IRIX5) || defined(OSF1)
  #   define RANDOM() random()
  # else
***************
*** 229,232 ****
--- 229,234 ----
  #endif /* KEEP_BACK_PTRS */
  
+ # define CROSSES_HBLK(p, sz) \
+       (((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)
  /* Store debugging info into p.  Return displaced pointer. */
  /* Assumes we don't hold allocation lock.                */
***************
*** 244,247 ****
--- 246,251 ----
      /* inconsistent while we're in the handler.                               
*/
      LOCK();
+     GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
+     GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
  #   ifdef KEEP_BACK_PTRS
        ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
***************
*** 276,279 ****
--- 280,285 ----
      /* But that's expensive.  And this way things should only appear  */
      /* inconsistent while we're in the handler.                               
*/
+     GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
+     GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
  #   ifdef KEEP_BACK_PTRS
        ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
***************
*** 325,328 ****
--- 331,335 ----
      register oh * ohdr = (oh *)GC_base(p);
      
+     GC_ASSERT(!I_HOLD_LOCK());
      GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));
      GC_err_puts(ohdr -> oh_string);
***************
*** 343,346 ****
--- 350,354 ----
  # endif
  {
+     GC_ASSERT(!I_HOLD_LOCK());
      if (GC_HAS_DEBUG_INFO(p)) {
        GC_print_obj(p);
***************
*** 356,359 ****
--- 364,368 ----
      register oh * ohdr = (oh *)GC_base(p);
      
+     GC_ASSERT(!I_HOLD_LOCK());
      GC_err_printf2("0x%lx in object at 0x%lx(", (unsigned long)clobbered_addr,
                                                (unsigned long)p);
***************
*** 377,380 ****
--- 386,391 ----
  void GC_check_heap_proc GC_PROTO((void));
  
+ void GC_print_all_smashed_proc GC_PROTO((void));
+ 
  void GC_do_nothing() {}
  
***************
*** 383,388 ****
--- 394,401 ----
  #   ifndef SHORT_DBG_HDRS
        GC_check_heap = GC_check_heap_proc;
+       GC_print_all_smashed = GC_print_all_smashed_proc;
  #   else
        GC_check_heap = GC_do_nothing;
+       GC_print_all_smashed = GC_do_nothing;
  #   endif
      GC_print_heap_obj = GC_debug_print_heap_obj_proc;
***************
*** 448,452 ****
          return(0);
      }
!     ADD_CALL_CHAIN(result, ra);
      return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
    }
--- 461,465 ----
          return(0);
      }
!     ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
      return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
    }
***************
*** 462,466 ****
          return(0);
      }
!     ADD_CALL_CHAIN(result, ra);
      return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
    }
--- 475,479 ----
          return(0);
      }
!     ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
      return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
    }
***************
*** 776,779 ****
--- 789,831 ----
  
  #ifndef SHORT_DBG_HDRS
+ 
+ /* List of smashed objects.  We defer printing these, since we can't  */
+ /* always print them nicely with the allocation lock held.            */
+ /* We put them here instead of in GC_arrays, since it may be useful to        
*/
+ /* be able to look at them with the debugger.                         */
+ #define MAX_SMASHED 20
+ ptr_t GC_smashed[MAX_SMASHED];
+ unsigned GC_n_smashed = 0;
+ 
+ # if defined(__STDC__) || defined(__cplusplus)
+     void GC_add_smashed(ptr_t smashed)
+ # else
+     void GC_add_smashed(smashed)
+     ptr_t smashed;
+ #endif
+ {
+     GC_ASSERT(GC_is_marked(GC_base(smashed)));
+     GC_smashed[GC_n_smashed] = smashed;
+     if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed;
+       /* In case of overflow, we keep the first MAX_SMASHED-1 */
+       /* entries plus the last one.                           */
+     GC_have_errors = TRUE;
+ }
+ 
+ /* Print all objects on the list.  Clear the list.    */
+ void GC_print_all_smashed_proc ()
+ {
+     unsigned i;
+ 
+     GC_ASSERT(!I_HOLD_LOCK());
+     if (GC_n_smashed == 0) return;
+     GC_err_printf0("GC_check_heap_block: found smashed heap objects:\n");
+     for (i = 0; i < GC_n_smashed; ++i) {
+         GC_print_smashed_obj(GC_base(GC_smashed[i]), GC_smashed[i]);
+       GC_smashed[i] = 0;
+     }
+     GC_n_smashed = 0;
+ }
+ 
  /* Check all marked objects in the given block for validity */
  /*ARGSUSED*/
***************
*** 804,812 ****
                ptr_t clobbered = GC_check_annotated_obj((oh *)p);
                
!               if (clobbered != 0) {
!                   GC_err_printf0(
!                       "GC_check_heap_block: found smashed location at ");
!                   GC_print_smashed_obj((ptr_t)p, clobbered);
!               }
            }
            word_no += sz;
--- 856,860 ----
                ptr_t clobbered = GC_check_annotated_obj((oh *)p);
                
!               if (clobbered != 0) GC_add_smashed(clobbered);
            }
            word_no += sz;

Index: dyn_load.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/dyn_load.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** dyn_load.c  8 Apr 2002 23:36:49 -0000       1.2
--- dyn_load.c  6 Feb 2003 01:35:45 -0000       1.3
***************
*** 356,363 ****
                continue;
            }
!           if (start <= datastart && end > datastart && maj_dev != 0) {
                /* Main data segment; discard   */
                continue;
!           }
  #         ifdef THREADS
              if (GC_segment_is_thread_stack(start, end)) continue;
--- 356,365 ----
                continue;
            }
! #         if 0
!             if (start <= datastart && end > datastart && maj_dev != 0) {
                /* Main data segment; discard   */
                continue;
!             }
! #         endif
  #         ifdef THREADS
              if (GC_segment_is_thread_stack(start, end)) continue;
***************
*** 385,388 ****
--- 387,397 ----
  }
  
+ /* We now take care of the main data segment ourselves: */
+ GC_bool GC_register_main_static_data()
+ {
+   return FALSE;
+ }
+   
+ # define HAVE_REGISTER_MAIN_STATIC_DATA
  //
  //  parse_map_entry parses an entry from /proc/self/maps so we can
***************
*** 394,397 ****
--- 403,409 ----
  //  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
***************
*** 399,406 ****
  //  trailing '\n'.)
  //
! #define OFFSET_MAP_START   0
! #define OFFSET_MAP_END     9
! #define OFFSET_MAP_PROT   18
! #define OFFSET_MAP_MAJDEV 32
  
  static char *parse_map_entry(char *buf_ptr, word *start, word *end,
--- 411,429 ----
  //  trailing '\n'.)
  //
! #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
  
  static char *parse_map_entry(char *buf_ptr, word *start, word *end,
***************
*** 408,412 ****
  {
      int i;
-     unsigned int val;
      char *tok;
  
--- 431,434 ----
***************
*** 421,429 ****
  
          tok = buf_ptr;
!         buf_ptr[OFFSET_MAP_START+8] = '\0';
          *start = strtoul(tok, NULL, 16);
  
          tok = buf_ptr+OFFSET_MAP_END;
!         buf_ptr[OFFSET_MAP_END+8] = '\0';
          *end = strtoul(tok, NULL, 16);
  
--- 443,451 ----
  
          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);
  
***************
*** 470,473 ****
--- 492,496 ----
      return -1;
  
+ # if 0 /* We now register the main program data here. */
    /* Skip the first object - it is the main program.  */
    if (*(int *)ptr == 0)
***************
*** 476,479 ****
--- 499,503 ----
        return 0;
      }
+ # endif
  
    p = info->dlpi_phdr;
***************
*** 511,514 ****
--- 535,546 ----
  }
  
+ /* Do we need to separately register the main static data segment? */
+ GC_bool GC_register_main_static_data()
+ {
+   return (dl_iterate_phdr == 0);
+ }
+ 
+ #define HAVE_REGISTER_MAIN_STATIC_DATA
+ 
  # else /* !LINUX || version(glibc) < 2.2.4 */
  
***************
*** 530,540 ****
  # endif
  
  static struct link_map *
  GC_FirstDLOpenedLinkMap()
  {
- #   ifdef __GNUC__
- #     pragma weak _DYNAMIC
- #   endif
-     extern ElfW(Dyn) _DYNAMIC[];
      ElfW(Dyn) *dp;
      struct r_debug *r;
--- 562,573 ----
  # endif
  
+ #ifdef __GNUC__
+ # pragma weak _DYNAMIC
+ #endif
+ extern ElfW(Dyn) _DYNAMIC[];
+ 
  static struct link_map *
  GC_FirstDLOpenedLinkMap()
  {
      ElfW(Dyn) *dp;
      struct r_debug *r;
***************
*** 776,783 ****
  # endif
  
! # ifndef MSWINCE
!   extern GC_bool GC_win32s;
! # endif
    
    void GC_register_dynamic_libraries()
    {
--- 809,829 ----
  # endif
  
! # ifdef MSWINCE
!   /* Do we need to separately register the main static data segment? */
!   GC_bool GC_register_main_static_data()
!   {
!     return FALSE;
!   }
! # else /* win32 */
!   extern GC_bool GC_no_win32_dlls;
! 
!   GC_bool GC_register_main_static_data()
!   {
!     return GC_no_win32_dlls;
!   }
! # endif /* win32 */
    
+ # define HAVE_REGISTER_MAIN_STATIC_DATA
+ 
    void GC_register_dynamic_libraries()
    {
***************
*** 790,794 ****
  
  #   ifdef MSWIN32
!       if (GC_win32s) return;
  #   endif
      base = limit = p = GC_sysinfo.lpMinimumApplicationAddress;
--- 836,840 ----
  
  #   ifdef MSWIN32
!       if (GC_no_win32_dlls) return;
  #   endif
      base = limit = p = GC_sysinfo.lpMinimumApplicationAddress;
***************
*** 1080,1082 ****
--- 1126,1139 ----
  
  #endif /* !PCR */
+ 
  #endif /* !DYNAMIC_LOADING */
+ 
+ #ifndef HAVE_REGISTER_MAIN_STATIC_DATA
+ 
+ /* Do we need to separately register the main static data segment? */
+ GC_bool GC_register_main_static_data()
+ {
+   return TRUE;
+ }
+ #endif /* HAVE_REGISTER_MAIN_STATIC_DATA */
+ 

Index: finalize.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/finalize.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** finalize.c  8 Apr 2002 23:36:49 -0000       1.2
--- finalize.c  6 Feb 2003 01:35:45 -0000       1.3
***************
*** 762,767 ****
  int GC_invoke_finalizers()
  {
!     register struct finalizable_object * curr_fo;
!     register int count = 0;
      DCL_LOCK_STATE;
      
--- 762,769 ----
  int GC_invoke_finalizers()
  {
!     struct finalizable_object * curr_fo;
!     int count = 0;
!     word mem_freed_before;
!     GC_bool first_time = TRUE;
      DCL_LOCK_STATE;
      
***************
*** 771,774 ****
--- 773,780 ----
            LOCK();
  #     endif
+       if (first_time) {
+           mem_freed_before = GC_mem_freed;
+           first_time = FALSE;
+       }
        curr_fo = GC_finalize_now;
  #     ifdef THREADS
***************
*** 792,795 ****
--- 798,806 ----
  #     endif
      }
+     if (mem_freed_before != GC_mem_freed) {
+         LOCK();
+       GC_finalizer_mem_freed += (GC_mem_freed - mem_freed_before);
+       UNLOCK();
+     }
      return count;
  }
***************
*** 804,808 ****
      if (!GC_finalize_on_demand) {
        (void) GC_invoke_finalizers();
!       GC_ASSERT(GC_finalize_now == 0);
        return;
      }
--- 815,821 ----
      if (!GC_finalize_on_demand) {
        (void) GC_invoke_finalizers();
! #     ifndef THREADS
!         GC_ASSERT(GC_finalize_now == 0);
! #     endif   /* Otherwise GC can run concurrently and add more */
        return;
      }
***************
*** 842,843 ****
--- 855,870 ----
  }
  
+ #if !defined(NO_DEBUGGING)
+ 
+ void GC_print_finalization_stats()
+ {
+     struct finalizable_object *fo = GC_finalize_now;
+     size_t ready = 0;
+ 
+     GC_printf2("%lu finalization table entries; %lu disappearing links\n",
+              GC_fo_entries, GC_dl_entries);
+     for (; 0 != fo; fo = fo_next(fo)) ++ready;
+     GC_printf1("%lu objects are eligible for immediate finalization\n", 
ready);
+ }
+ 
+ #endif /* NO_DEBUGGING */

Index: gc_cpp.cc
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/gc_cpp.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** gc_cpp.cc   8 Apr 2002 23:36:50 -0000       1.2
--- gc_cpp.cc   6 Feb 2003 01:35:45 -0000       1.3
***************
*** 33,37 ****
      GC_FREE( obj );}
    
! #ifdef OPERATOR_NEW_ARRAY
  
  void* operator new[]( size_t size ) {
--- 33,37 ----
      GC_FREE( obj );}
    
! #ifdef GC_OPERATOR_NEW_ARRAY
  
  void* operator new[]( size_t size ) {
***************
*** 41,45 ****
      GC_FREE( obj );}
  
! #endif /* OPERATOR_NEW_ARRAY */
  
  #ifdef _MSC_VER
--- 41,45 ----
      GC_FREE( obj );}
  
! #endif /* GC_OPERATOR_NEW_ARRAY */
  
  #ifdef _MSC_VER

Index: gc_dlopen.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/gc_dlopen.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** gc_dlopen.c 8 Apr 2002 23:36:50 -0000       1.2
--- gc_dlopen.c 6 Feb 2003 01:35:45 -0000       1.3
***************
*** 20,24 ****
   * This used to be in dyn_load.c.  It was extracted into a separate file
   * to avoid having to link against libdl.{a,so} if the client doesn't call
!  * dlopen.  -HB
   */
  
--- 20,25 ----
   * This used to be in dyn_load.c.  It was extracted into a separate file
   * to avoid having to link against libdl.{a,so} if the client doesn't call
!  * dlopen.  Of course this fails if the collector is in a dynamic
!  * library. -HB
   */
  
***************
*** 45,61 ****
    /* initialization code allocates substantial amounts of GC'ed memory.       
*/
    /* But I don't know of a better solution.                           */
!   /* This can still deadlock if the client explicitly starts a GC     */
!   /* during the dlopen.  He shouldn't do that.                                
*/
!   static GC_bool disable_gc_for_dlopen()
    {
-     GC_bool result;
      LOCK();
-     result = GC_dont_gc;
      while (GC_incremental && GC_collection_in_progress()) {
        GC_collect_a_little_inner(1000);
      }
!     GC_dont_gc = TRUE;
      UNLOCK();
-     return(result);
    }
  
--- 46,57 ----
    /* initialization code allocates substantial amounts of GC'ed memory.       
*/
    /* But I don't know of a better solution.                           */
!   static void disable_gc_for_dlopen()
    {
      LOCK();
      while (GC_incremental && GC_collection_in_progress()) {
        GC_collect_a_little_inner(1000);
      }
!     ++GC_dont_gc;
      UNLOCK();
    }
  
***************
*** 75,82 ****
  {
      void * result;
-     GC_bool dont_gc_save;
      
  #   ifndef USE_PROC_FOR_LIBRARIES
!       dont_gc_save = disable_gc_for_dlopen();
  #   endif
  #   ifdef GC_USE_LD_WRAP
--- 71,77 ----
  {
      void * result;
      
  #   ifndef USE_PROC_FOR_LIBRARIES
!       disable_gc_for_dlopen();
  #   endif
  #   ifdef GC_USE_LD_WRAP
***************
*** 86,90 ****
  #   endif
  #   ifndef USE_PROC_FOR_LIBRARIES
!       GC_dont_gc = dont_gc_save;
  #   endif
      return(result);
--- 81,85 ----
  #   endif
  #   ifndef USE_PROC_FOR_LIBRARIES
!       GC_enable(); /* undoes disable_gc_for_dlopen */
  #   endif
      return(result);

Index: if_mach.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/if_mach.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** if_mach.c   9 Nov 2001 02:20:30 -0000       1.1.1.1
--- if_mach.c   6 Feb 2003 01:35:45 -0000       1.2
***************
*** 15,19 ****
      if (strcmp(OS_TYPE, "") != 0 && strcmp(argv[2], "") != 0
          && strcmp(OS_TYPE, argv[2]) != 0) return(0);
!     printf("^^^^Starting command^^^^\n");
      fflush(stdout);
      execvp(argv[3], argv+3);
--- 15,19 ----
      if (strcmp(OS_TYPE, "") != 0 && strcmp(argv[2], "") != 0
          && strcmp(OS_TYPE, argv[2]) != 0) return(0);
!     fprintf(stderr, "^^^^Starting command^^^^\n");
      fflush(stdout);
      execvp(argv[3], argv+3);

Index: install-sh
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/install-sh,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** install-sh  9 Nov 2001 02:20:55 -0000       1.1.1.1
--- install-sh  6 Feb 2003 01:35:45 -0000       1.2
***************
*** 110,114 ****
        exit 1
  else
!       true
  fi
  
--- 110,114 ----
        exit 1
  else
!       :
  fi
  
***************
*** 121,125 ****
                chmodcmd=""
        else
!               instcmd=mkdir
        fi
  else
--- 121,125 ----
                chmodcmd=""
        else
!               instcmd=$mkdirprog
        fi
  else
***************
*** 131,135 ****
        if [ -f $src -o -d $src ]
        then
!               true
        else
                echo "install:  $src does not exist"
--- 131,135 ----
        if [ -f $src -o -d $src ]
        then
!               :
        else
                echo "install:  $src does not exist"
***************
*** 142,146 ****
                exit 1
        else
!               true
        fi
  
--- 142,146 ----
                exit 1
        else
!               :
        fi
  
***************
*** 152,156 ****
                dst="$dst"/`basename $src`
        else
!               true
        fi
  fi
--- 152,156 ----
                dst="$dst"/`basename $src`
        else
!               :
        fi
  fi
***************
*** 164,169 ****
  # Skip lots of stat calls in the usual case.
  if [ ! -d "$dstdir" ]; then
! defaultIFS='  
! '
  IFS="${IFS-${defaultIFS}}"
  
--- 164,169 ----
  # Skip lots of stat calls in the usual case.
  if [ ! -d "$dstdir" ]; then
! defaultIFS='
!       '
  IFS="${IFS-${defaultIFS}}"
  
***************
*** 184,188 ****
                $mkdirprog "${pathcomp}"
        else
!               true
        fi
  
--- 184,188 ----
                $mkdirprog "${pathcomp}"
        else
!               :
        fi
  
***************
*** 195,202 ****
        $doit $instcmd $dst &&
  
!       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
!       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
!       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
!       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
  else
  
--- 195,202 ----
        $doit $instcmd $dst &&
  
!       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
!       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
!       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
!       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
  else
  
***************
*** 217,221 ****
                dstfile=`basename $dst`
        else
!               true
        fi
  
--- 217,221 ----
                dstfile=`basename $dst`
        else
!               :
        fi
  
***************
*** 236,243 ****
  # errors from the above "$doit $instcmd $src $dsttmp" command.
  
!       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
!       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
!       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
!       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
  
  # Now rename the file to the real destination.
--- 236,243 ----
  # errors from the above "$doit $instcmd $src $dsttmp" command.
  
!       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
!       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
!       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
!       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
  
  # Now rename the file to the real destination.

Index: irix_threads.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/irix_threads.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** irix_threads.c      8 Apr 2002 23:36:50 -0000       1.2
--- irix_threads.c      6 Feb 2003 01:35:45 -0000       1.3
***************
*** 524,528 ****
      thread_gc_id = GC_lookup_thread(thread);
      UNLOCK();
!     result = REAL_FUNC(pthread_detach)(thread);
      if (result == 0) {
        LOCK();
--- 524,528 ----
      thread_gc_id = GC_lookup_thread(thread);
      UNLOCK();
!     result = pthread_detach(thread);
      if (result == 0) {
        LOCK();
***************
*** 604,608 ****
      si -> arg = arg;
      LOCK();
!     if (!GC_initialized) GC_init();
      if (NULL == attr) {
          stack = 0;
--- 604,608 ----
      si -> arg = arg;
      LOCK();
!     if (!GC_is_initialized) GC_init();
      if (NULL == attr) {
          stack = 0;

Index: linux_threads.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/linux_threads.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** linux_threads.c     8 Apr 2002 23:36:50 -0000       1.2
--- linux_threads.c     6 Feb 2003 01:35:45 -0000       1.3
***************
*** 4,8 ****
   * Copyright (c) 1998 by Fergus Henderson.  All rights reserved.
   * Copyright (c) 2000-2001 by Hewlett-Packard Company.  All rights reserved.
-  * DG/UX ix86 support <address@hidden>
   *
   * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
--- 4,7 ----
***************
*** 28,31 ****
--- 27,31 ----
   * made here may need to be reflected there too.
   */
+  /* DG/UX ix86 support <address@hidden> */
  /*
   * Linux_threads.c now also includes some code to support HPUX and
***************
*** 55,59 ****
  
  # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
!      && !defined(GC_IRIX_THREADS)
  
  # include "private/gc_priv.h"
--- 55,59 ----
  
  # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
!      && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
  
  # include "private/gc_priv.h"
***************
*** 64,68 ****
  # endif
  
! # if defined(GC_DGUX386_THREADS) && !defined(USE_PTHREAD_SPECIFIC)
  #   define USE_PTHREAD_SPECIFIC
  # endif
--- 64,69 ----
  # endif
  
! # if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS)) \
!       && !defined(USE_PTHREAD_SPECIFIC)
  #   define USE_PTHREAD_SPECIFIC
  # endif
***************
*** 137,141 ****
  void GC_thr_init();
  
! #if 0
  void GC_print_sig_mask()
  {
--- 138,155 ----
  void GC_thr_init();
  
! #if DEBUG_THREADS
! 
! #ifndef NSIG
! # if defined(MAXSIG)
! #  define NSIG (MAXSIG+1)
! # elif defined(_NSIG)
! #  define NSIG _NSIG
! # elif defined(__SIGRTMAX)
! #  define NSIG (__SIGRTMAX+1)
! # else
!   --> please fix it
! # endif
! #endif
! 
  void GC_print_sig_mask()
  {
***************
*** 146,150 ****
        ABORT("pthread_sigmask");
      GC_printf0("Blocked: ");
!     for (i = 1; i <= MAXSIG; i++) {
          if (sigismember(&blocked, i)) { GC_printf1("%ld ",(long) i); }
      }
--- 160,164 ----
        ABORT("pthread_sigmask");
      GC_printf0("Blocked: ");
!     for (i = 1; i < NSIG; i++) {
          if (sigismember(&blocked, i)) { GC_printf1("%ld ",(long) i); }
      }
***************
*** 153,156 ****
--- 167,177 ----
  #endif
  
+ word GC_stop_count;   /* Incremented at the beginning of GC_stop_world. */
+ 
+ #ifdef GC_OSF1_THREADS
+   GC_bool GC_retry_signals = TRUE;
+ #else
+   GC_bool GC_retry_signals = FALSE;
+ #endif
  
  /* We use the allocation lock to protect thread-related data structures. */
***************
*** 190,193 ****
--- 211,217 ----
                                /* reclamation of any data it might     */
                                /* reference.                           */
+     word last_stop_count;     /* GC_last_stop_count value when thread */
+                               /* last successfully handled a suspend  */
+                               /* signal.                              */
  #   ifdef THREAD_LOCAL_ALLOC
  #     if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
***************
*** 444,448 ****
            return result;
        } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
!           *my_fl = my_entry + index + 1;
              return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
        } else {
--- 468,474 ----
            return result;
        } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
!           if (!GC_incremental) *my_fl = my_entry + index + 1;
!               /* In the incremental case, we always have to take this */
!               /* path.  Thus we leave the counter alone.              */
              return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
        } else {
***************
*** 476,480 ****
  #ifndef SIG_THR_RESTART
  #  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
! #   define SIG_THR_RESTART _SIGRTMIN + 5
  #  else
  #   define SIG_THR_RESTART SIGXCPU
--- 502,510 ----
  #ifndef SIG_THR_RESTART
  #  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
! #    ifdef _SIGRTMIN
! #      define SIG_THR_RESTART _SIGRTMIN + 5
! #    else
! #      define SIG_THR_RESTART SIGRTMIN + 5
! #    endif
  #  else
  #   define SIG_THR_RESTART SIGXCPU
***************
*** 613,621 ****
        /* suspension, i.e. the marker can't have incremented it yet.   */
  #   endif
  
      if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
  
  #if DEBUG_THREADS
!     GC_printf1("Suspending 0x%x\n", my_thread);
  #endif
  
--- 643,652 ----
        /* suspension, i.e. the marker can't have incremented it yet.   */
  #   endif
+     word my_stop_count = GC_stop_count;
  
      if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
  
  #if DEBUG_THREADS
!     GC_printf1("Suspending 0x%lx\n", my_thread);
  #endif
  
***************
*** 625,628 ****
--- 656,667 ----
      /* to stop the world.  Thus concurrent modification of the        */
      /* data structure is impossible.                          */
+     if (me -> last_stop_count == my_stop_count) {
+       /* Duplicate signal.  OK if we are retrying.    */
+       if (!GC_retry_signals) {
+           WARN("Duplicate suspend signal in thread %lx\n",
+                pthread_self());
+       }
+       return;
+     }
  #   ifdef SPARC
        me -> stack_ptr = (ptr_t)GC_save_regs_in_stack();
***************
*** 638,641 ****
--- 677,681 ----
      /* the only async-signal-safe primitive in LinuxThreads.    */
      sem_post(&GC_suspend_ack_sem);
+     me -> last_stop_count = my_stop_count;
  
      /* Wait until that thread tells us to restart by sending    */
***************
*** 655,661 ****
            sigsuspend(&mask);             /* Wait for signal */
      } while (me->signal != SIG_THR_RESTART);
  
  #if DEBUG_THREADS
!     GC_printf1("Continuing 0x%x\n", my_thread);
  #endif
  }
--- 695,707 ----
            sigsuspend(&mask);             /* Wait for signal */
      } while (me->signal != SIG_THR_RESTART);
+     /* 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.                                
    */ 
  
  #if DEBUG_THREADS
!     GC_printf1("Continuing 0x%lx\n", my_thread);
  #endif
  }
***************
*** 684,688 ****
  
  #if DEBUG_THREADS
!     GC_printf1("In GC_restart_handler for 0x%x\n", pthread_self());
  #endif
  }
--- 730,734 ----
  
  #if DEBUG_THREADS
!     GC_printf1("In GC_restart_handler for 0x%lx\n", pthread_self());
  #endif
  }
***************
*** 709,712 ****
--- 755,762 ----
  {
      GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
+ #   if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
+       GC_push_all((ptr_t)(&GC_thread_key),
+         (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key));
+ #   endif
  }
  
***************
*** 859,890 ****
  int GC_stopping_pid;
  
! /* Caller holds allocation lock.      */
! void GC_stop_world()
  {
      pthread_t my_thread = pthread_self();
-     register int i;
-     register GC_thread p;
-     register int n_live_threads = 0;
-     register int result;
  
      GC_stopping_thread = my_thread;    /* debugging only.      */
      GC_stopping_pid = getpid();                /* debugging only.      */
-     /* Make sure all free list construction has stopped before we start. */
-     /* No new construction can start, since free list construction is */
-     /* required to acquire and release the GC lock before it starts,  */
-     /* and we have the lock.                                          */
- #   ifdef PARALLEL_MARK
-       GC_acquire_mark_lock();
-       GC_ASSERT(GC_fl_builder_count == 0);
-       /* We should have previously waited for it to become zero. */
- #   endif /* PARALLEL_MARK */
      for (i = 0; i < THREAD_TABLE_SZ; i++) {
        for (p = GC_threads[i]; p != 0; p = p -> next) {
          if (p -> id != my_thread) {
              if (p -> flags & FINISHED) continue;
            if (p -> thread_blocked) /* Will wait */ continue;
              n_live_threads++;
            #if DEBUG_THREADS
!             GC_printf1("Sending suspend signal to 0x%x\n", p -> id);
            #endif
              result = pthread_kill(p -> id, SIG_SUSPEND);
--- 909,934 ----
  int GC_stopping_pid;
  
! /* We hold the allocation lock.  Suspend all threads that might       */
! /* still be running.  Return the number of suspend signals that       */
! /* were sent.                                                 */
! int GC_suspend_all()
  {
+     int n_live_threads = 0;
+     int i;
+     GC_thread p;
+     int result;
      pthread_t my_thread = pthread_self();
  
      GC_stopping_thread = my_thread;    /* debugging only.      */
      GC_stopping_pid = getpid();                /* debugging only.      */
      for (i = 0; i < THREAD_TABLE_SZ; i++) {
        for (p = GC_threads[i]; p != 0; p = p -> next) {
          if (p -> id != my_thread) {
              if (p -> flags & FINISHED) continue;
+           if (p -> last_stop_count == GC_stop_count) continue;
            if (p -> thread_blocked) /* Will wait */ continue;
              n_live_threads++;
            #if DEBUG_THREADS
!             GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
            #endif
              result = pthread_kill(p -> id, SIG_SUSPEND);
***************
*** 902,905 ****
--- 946,998 ----
        }
      }
+     return n_live_threads;
+ }
+ 
+ /* Caller holds allocation lock.      */
+ void GC_stop_world()
+ {
+     register int i;
+     register int n_live_threads;
+ 
+     /* Make sure all free list construction has stopped before we start. */
+     /* No new construction can start, since free list construction is */
+     /* required to acquire and release the GC lock before it starts,  */
+     /* and we have the lock.                                          */
+ #   ifdef PARALLEL_MARK
+       GC_acquire_mark_lock();
+       GC_ASSERT(GC_fl_builder_count == 0);
+       /* We should have previously waited for it to become zero. */
+ #   endif /* PARALLEL_MARK */
+     ++GC_stop_count;
+     n_live_threads = GC_suspend_all();
+     if (GC_retry_signals) {
+       unsigned long wait_usecs = 0;  /* Total wait since retry.       */
+ #     define WAIT_UNIT 3000
+ #     define RETRY_INTERVAL 100000
+       for (;;) {
+           int ack_count;
+ 
+           sem_getvalue(&GC_suspend_ack_sem, &ack_count);
+           if (ack_count == n_live_threads) break;
+           if (wait_usecs > RETRY_INTERVAL) {
+               int newly_sent = GC_suspend_all();
+ 
+ #               ifdef CONDPRINT
+                   if (GC_print_stats) {
+                   GC_printf1("Resent %ld signals after timeout\n",
+                              newly_sent);
+                 }
+ #               endif
+               sem_getvalue(&GC_suspend_ack_sem, &ack_count);
+               if (newly_sent < n_live_threads - ack_count) {
+                   WARN("Lost some threads during GC_stop_world?!\n",0);
+                   n_live_threads = ack_count + newly_sent;
+               }
+               wait_usecs = 0;
+           }
+           usleep(WAIT_UNIT);
+           wait_usecs += WAIT_UNIT;
+       }
+     }
      for (i = 0; i < n_live_threads; i++) {
        if (0 != sem_wait(&GC_suspend_ack_sem))
***************
*** 910,914 ****
  #   endif
      #if DEBUG_THREADS
!       GC_printf1("World stopped 0x%x\n", pthread_self());
      #endif
      GC_stopping_thread = 0;  /* debugging only */
--- 1003,1007 ----
  #   endif
      #if DEBUG_THREADS
!       GC_printf1("World stopped from 0x%lx\n", pthread_self());
      #endif
      GC_stopping_thread = 0;  /* debugging only */
***************
*** 936,940 ****
              n_live_threads++;
            #if DEBUG_THREADS
!             GC_printf1("Sending restart signal to 0x%x\n", p -> id);
            #endif
              result = pthread_kill(p -> id, SIG_THR_RESTART);
--- 1029,1033 ----
              n_live_threads++;
            #if DEBUG_THREADS
!             GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
            #endif
              result = pthread_kill(p -> id, SIG_THR_RESTART);
***************
*** 1083,1086 ****
--- 1176,1180 ----
        }
      }
+     close(f);
      return result;
  }
***************
*** 1238,1241 ****
--- 1332,1348 ----
        t -> flags = DETACHED | MAIN_THREAD;
  
+     /* Check for GC_RETRY_SIGNALS.    */
+       if (0 != GETENV("GC_RETRY_SIGNALS")) {
+         GC_retry_signals = TRUE;
+       }
+       if (0 != GETENV("GC_NO_RETRY_SIGNALS")) {
+         GC_retry_signals = FALSE;
+       }
+ #     ifdef CONDPRINT
+           if (GC_print_stats && GC_retry_signals) {
+               GC_printf0("Will retry suspend signal if necessary.\n");
+         }
+ #     endif
+ 
      /* Set GC_nprocs.  */
        {
***************
*** 1248,1252 ****
          GC_nprocs = pthread_num_processors_np();
  #       endif
! #       if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS)
            GC_nprocs = 1;
  #       endif
--- 1355,1363 ----
          GC_nprocs = pthread_num_processors_np();
  #       endif
! #     if defined(GC_OSF1_THREADS)
!         GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN);
!         if (GC_nprocs <= 0) GC_nprocs = 1;
! #     endif
! #       if defined(GC_FREEBSD_THREADS)
            GC_nprocs = 1;
  #       endif
***************
*** 1747,1752 ****
          }
  #       define SLEEP_THRESHOLD 12
!               /* nanosleep(<= 2ms) just spins under Linux.  We        */
!               /* want to be careful to avoid that behavior.           */
          if (i < SLEEP_THRESHOLD) {
              sched_yield();
--- 1858,1867 ----
          }
  #       define SLEEP_THRESHOLD 12
!               /* Under Linux very short sleeps tend to wait until     */
!               /* the current time quantum expires.  On old Linux      */
!               /* kernels nanosleep(<= 2ms) just spins under Linux.    */
!               /* (Under 2.4, this happens only for real-time          */
!               /* processes.)  We want to minimize both behaviors      */
!               /* here.                                                */
          if (i < SLEEP_THRESHOLD) {
              sched_yield();

Index: mach_dep.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/mach_dep.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** mach_dep.c  8 Apr 2002 23:36:50 -0000       1.2
--- mach_dep.c  6 Feb 2003 01:35:45 -0000       1.3
***************
*** 82,102 ****
  #       endif
  
- #       if defined(MIPS) && defined(LINUX)
-         /* I'm not sure whether this has actually been tested. */
- #         define call_push(x)     asm("move $4," x ";"); asm("jal 
GC_push_one")
-         call_push("$2");
-         call_push("$3");
-         call_push("$16");
-         call_push("$17");
-         call_push("$18");
-         call_push("$19");
-         call_push("$20");
-         call_push("$21");
-         call_push("$22");
-         call_push("$23");
-         call_push("$30");
- #         undef call_push
- #       endif /* MIPS && LINUX */
- 
  #       ifdef VAX
          /* VAX - generic code below does not work under 4.2 */
--- 82,85 ----

Index: malloc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/malloc.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** malloc.c    8 Apr 2002 23:36:50 -0000       1.2
--- malloc.c    6 Feb 2003 01:35:45 -0000       1.3
***************
*** 183,186 ****
--- 183,187 ----
      DCL_LOCK_STATE;
  
+     if (GC_have_errors) GC_print_all_errors();
      GC_INVOKE_FINALIZERS();
      if (SMALL_OBJ(lb)) {
***************
*** 295,298 ****
--- 296,304 ----
          }
          /* See above comment on signals.      */
+       GC_ASSERT(0 == obj_link(op)
+                 || (word)obj_link(op)
+                       <= (word)GC_greatest_plausible_heap_addr
+                    && (word)obj_link(op)
+                       >= (word)GC_least_plausible_heap_addr);
          *opp = obj_link(op);
          obj_link(op) = 0;
***************
*** 339,342 ****
--- 345,349 ----
    }
  
+ #ifndef strdup
  # include <string.h>
  # ifdef __STDC__
***************
*** 347,355 ****
  # endif
    {
!     size_t len = strlen + 1;
      char * result = ((char *)REDIRECT_MALLOC(len+1));
      BCOPY(s, result, len+1);
      return result;
    }
  # endif /* REDIRECT_MALLOC */
  
--- 354,367 ----
  # endif
    {
!     size_t len = strlen(s) + 1;
      char * result = ((char *)REDIRECT_MALLOC(len+1));
      BCOPY(s, result, len+1);
      return result;
    }
+ #endif /* !defined(strdup) */
+  /* If strdup is macro defined, we assume that it actually calls malloc, */
+  /* and thus the right thing will happen even without overriding it.   */
+  /* This seems to be true on most Linux systems.                       */
+ 
  # endif /* REDIRECT_MALLOC */
  
***************
*** 374,377 ****
--- 386,390 ----
      h = HBLKPTR(p);
      hhdr = HDR(h);
+     GC_ASSERT(GC_base(p) == p);
  #   if defined(REDIRECT_MALLOC) && \
        (defined(GC_SOLARIS_THREADS) || defined(GC_LINUX_THREADS) \
***************
*** 455,459 ****
  #endif /* THREADS */
  
! # ifdef REDIRECT_MALLOC
  #   ifdef __STDC__
        void free(GC_PTR p)
--- 468,475 ----
  #endif /* THREADS */
  
! # if defined(REDIRECT_MALLOC) && !defined(REDIRECT_FREE)
! #   define REDIRECT_FREE GC_free
! # endif
! # ifdef REDIRECT_FREE
  #   ifdef __STDC__
        void free(GC_PTR p)
***************
*** 464,468 ****
    {
  #   ifndef IGNORE_FREE
!       GC_free(p);
  #   endif
    }
--- 480,484 ----
    {
  #   ifndef IGNORE_FREE
!       REDIRECT_FREE(p);
  #   endif
    }

Index: mallocx.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/mallocx.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** mallocx.c   8 Apr 2002 23:36:50 -0000       1.2
--- mallocx.c   6 Feb 2003 01:35:45 -0000       1.3
***************
*** 143,147 ****
  }
  
! # if defined(REDIRECT_MALLOC) || defined(REDIRECT_REALLOC)
  # ifdef __STDC__
      GC_PTR realloc(GC_PTR p, size_t lb)
--- 143,151 ----
  }
  
! # if defined(REDIRECT_MALLOC) && !defined(REDIRECT_REALLOC)
! #   define REDIRECT_REALLOC GC_realloc
! # endif
! 
! # ifdef REDIRECT_REALLOC
  # ifdef __STDC__
      GC_PTR realloc(GC_PTR p, size_t lb)
***************
*** 152,162 ****
  # endif
    {
! #   ifdef REDIRECT_REALLOC
!       return(REDIRECT_REALLOC(p, lb));
! #   else
!       return(GC_realloc(p, lb));
! #   endif
    }
! # endif /* REDIRECT_MALLOC */
  
  
--- 156,162 ----
  # endif
    {
!     return(REDIRECT_REALLOC(p, lb));
    }
! # endif /* REDIRECT_REALLOC */
  
  
***************
*** 178,181 ****
--- 178,182 ----
      n_blocks = OBJ_SZ_TO_BLOCKS(lw);
      init = GC_obj_kinds[k].ok_init;
+     if (GC_have_errors) GC_print_all_errors();
      GC_INVOKE_FINALIZERS();
      DISABLE_SIGNALS();
***************
*** 287,290 ****
--- 288,292 ----
  DCL_LOCK_STATE;
  
+     if (GC_have_errors) GC_print_all_errors();
      GC_INVOKE_FINALIZERS();
      DISABLE_SIGNALS();
***************
*** 355,358 ****
--- 357,361 ----
      }
      lw = ALIGNED_WORDS(lb);
+     if (GC_have_errors) GC_print_all_errors();
      GC_INVOKE_FINALIZERS();
      DISABLE_SIGNALS();
***************
*** 576,579 ****
--- 579,620 ----
      }
  }
+ 
+ #ifdef __STDC__
+ /* Not well tested nor integrated.    */
+ /* Debug version is tricky and currently missing.     */
+ #include <limits.h>
+ 
+ GC_PTR GC_memalign(size_t align, size_t lb) 
+ { 
+     size_t new_lb;
+     size_t offset;
+     ptr_t result;
+ 
+ #   ifdef ALIGN_DOUBLE
+       if (align <= WORDS_TO_BYTES(2) && lb > align) return GC_malloc(lb);
+ #   endif
+     if (align <= WORDS_TO_BYTES(1)) return GC_malloc(lb);
+     if (align >= HBLKSIZE/2 || lb >= HBLKSIZE/2) {
+         if (align > HBLKSIZE) return GC_oom_fn(LONG_MAX-1024) /* Fail */;
+       return GC_malloc(lb <= HBLKSIZE? HBLKSIZE : lb);
+           /* Will be HBLKSIZE aligned.        */
+     }
+     /* We could also try to make sure that the real rounded-up object size */
+     /* is a multiple of align.  That would be correct up to HBLKSIZE.    */
+     new_lb = lb + align - 1;
+     result = GC_malloc(new_lb);
+     offset = (word)result % align;
+     if (offset != 0) {
+       offset = align - offset;
+         if (!GC_all_interior_pointers) {
+           if (offset >= VALID_OFFSET_SZ) return GC_malloc(HBLKSIZE);
+           GC_register_displacement(offset);
+       }
+     }
+     result = (GC_PTR) ((ptr_t)result + offset);
+     GC_ASSERT((word)result % align == 0);
+     return result;
+ }
+ #endif 
  
  # ifdef ATOMIC_UNCOLLECTABLE

Index: mark.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/mark.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** mark.c      16 Dec 2002 03:25:51 -0000      1.4
--- mark.c      6 Feb 2003 01:35:46 -0000       1.5
***************
*** 20,29 ****
  # include "private/gc_pmark.h"
  
- /* Temporary hack to work around cygwin 1.3 compile issues */
- #if defined(__CYGWIN__) || defined(__MINGW32__)
- #define       __try
- #define       __except(x)     if(0)
- #endif
- 
  /* We put this here to minimize the risk of inlining. */
  /*VARARGS*/
--- 20,23 ----
***************
*** 271,275 ****
  ptr_t cold_gc_frame;
  {
! #ifdef MSWIN32
    /* Windows 98 appears to asynchronously create and remove writable  */
    /* memory mappings, for reasons we haven't yet understood.  Since   */
--- 265,269 ----
  ptr_t cold_gc_frame;
  {
! #if defined(MSWIN32) && !defined(__GNUC__)
    /* Windows 98 appears to asynchronously create and remove writable  */
    /* memory mappings, for reasons we haven't yet understood.  Since   */
***************
*** 281,285 ****
    /* fault.                                                           */
    __try {
! #endif
      switch(GC_mark_state) {
        case MS_NONE:
--- 275,279 ----
    /* fault.                                                           */
    __try {
! #endif /* defined(MSWIN32) && !defined(__GNUC__) */
      switch(GC_mark_state) {
        case MS_NONE:
***************
*** 402,406 ****
            return(FALSE);
      }
! #ifdef MSWIN32
    } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
--- 396,400 ----
            return(FALSE);
      }
! #if defined(MSWIN32) && !defined(__GNUC__)
    } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
***************
*** 417,421 ****
      return FALSE;
    }
! #endif /* MSWIN32 */
  }
  
--- 411,415 ----
      return FALSE;
    }
! #endif /* defined(MSWIN32) && !defined(__GNUC__) */
  }
  
***************
*** 546,549 ****
--- 540,545 ----
            /* Process part of the range to avoid pushing too much on the       
*/
            /* stack.                                                   */
+         GC_ASSERT(descr < (word)GC_greatest_plausible_heap_addr
+                           - (word)GC_least_plausible_heap_addr);
  #       ifdef PARALLEL_MARK
  #         define SHARE_BYTES 2048
***************
*** 551,556 ****
                && mark_stack_top < mark_stack_limit - 1) {
              int new_size = (descr/2) & ~(sizeof(word)-1);
-             GC_ASSERT(descr < GC_greatest_plausible_heap_addr
-                               - GC_least_plausible_heap_addr);
              mark_stack_top -> mse_start = current_p;
              mark_stack_top -> mse_descr = new_size + sizeof(word);
--- 547,550 ----
***************
*** 578,581 ****
--- 572,576 ----
              if ((signed_word)descr < 0) {
                current = *current_p;
+             FIXUP_POINTER(current);
              if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
                PREFETCH(current);
***************
*** 652,655 ****
--- 647,651 ----
          GC_ASSERT(limit >= current_p);
          deferred = *limit;
+         FIXUP_POINTER(deferred);
          limit = (word *)((char *)limit - ALIGNMENT);
          if ((ptr_t)deferred >= least_ha && (ptr_t)deferred <  greatest_ha) {
***************
*** 661,664 ****
--- 657,661 ----
          /* based on limit.                                            */
          deferred = *limit;
+         FIXUP_POINTER(deferred);
          limit = (word *)((char *)limit - ALIGNMENT);
          if ((ptr_t)deferred >= least_ha && (ptr_t)deferred <  greatest_ha) {
***************
*** 675,678 ****
--- 672,676 ----
        /* we don't.                                            */
          current = *current_p;
+       FIXUP_POINTER(current);
          PREFETCH((ptr_t)current_p + PREF_DIST*CACHE_LINE_SIZE);
          if ((ptr_t)current >= least_ha && (ptr_t)current <  greatest_ha) {
***************
*** 726,734 ****
--- 724,748 ----
      unsigned i = 0;
  
+     /* Make sure that prior writes to the mark stack are visible. */
+     /* On some architectures, the fact that the reads are       */
+     /* volatile should suffice.                                         */
+ #   if !defined(IA64) && !defined(HP_PA) && !defined(I386)
+       GC_memory_barrier();
+ #   endif
      GC_ASSERT(high >= low-1 && high - low + 1 <= GC_mark_stack_size);
      for (p = low; p <= high && i <= max; ++p) {
        word descr = *(volatile word *) &(p -> mse_descr);
+       /* In the IA64 memory model, the following volatile store is    */
+       /* ordered after this read of descr.  Thus a thread must read   */
+       /* the original nonzero value.  HP_PA appears to be similar,    */
+       /* and if I'm reading the P4 spec correctly, X86 is probably    */
+       /* also OK.  In some other cases we need a barrier.             */
+ #       if !defined(IA64) && !defined(HP_PA) && !defined(I386)
+           GC_memory_barrier();
+ #       endif
        if (descr != 0) {
            *(volatile word *) &(p -> mse_descr) = 0;
+           /* More than one thread may get this entry, but that's only */
+           /* a minor performance problem.                             */
            ++top;
            top -> mse_descr = descr;
***************
*** 737,745 ****
                        top -> mse_descr < GC_greatest_plausible_heap_addr
                                           - GC_least_plausible_heap_addr);
-           /* There is no synchronization here.  We assume that at     */
-           /* least one thread will see the original descriptor.       */
-           /* Otherwise we need a barrier.                             */
-           /* More than one thread may get this entry, but that's only */
-           /* a minor performance problem.                             */
            /* If this is a big object, count it as                     */
            /* size/256 + 1 objects.                                    */
--- 751,754 ----
***************
*** 778,782 ****
        GC_ASSERT(GC_mark_stack_top = my_top);
  #     if !defined(IA64) && !defined(HP_PA)
!         GC_memory_write_barrier();
  #     endif
        /* On IA64, the volatile write acts as a release barrier. */
--- 787,791 ----
        GC_ASSERT(GC_mark_stack_top = my_top);
  #     if !defined(IA64) && !defined(HP_PA)
!         GC_memory_barrier();
  #     endif
        /* On IA64, the volatile write acts as a release barrier. */
***************
*** 1342,1347 ****
  
      if (top == 0) return;
!     /* check all pointers in range and put in push if they appear */
!     /* to be valid.                                             */
        lim = t - 1 /* longword */;
        for (p = b; p <= lim; p = (word *)(((char *)p) + ALIGNMENT)) {
--- 1351,1356 ----
  
      if (top == 0) return;
!     /* check all pointers in range and push if they appear    */
!     /* to be valid.                                           */
        lim = t - 1 /* longword */;
        for (p = b; p <= lim; p = (word *)(((char *)p) + ALIGNMENT)) {
***************
*** 1366,1370 ****
  ptr_t cold_gc_frame;
  {
!   if (GC_all_interior_pointers) {
  #   define EAGER_BYTES 1024
      /* Push the hot end of the stack eagerly, so that register values   */
--- 1375,1379 ----
  ptr_t cold_gc_frame;
  {
!   if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
  #   define EAGER_BYTES 1024
      /* Push the hot end of the stack eagerly, so that register values   */
***************
*** 1375,1378 ****
--- 1384,1388 ----
        return;
      }
+     GC_ASSERT(bottom <= cold_gc_frame && cold_gc_frame <= top);
  #   ifdef STACK_GROWS_DOWN
        GC_push_all(cold_gc_frame - sizeof(ptr_t), top);
***************
*** 1395,1399 ****
  ptr_t top;
  {
!   if (GC_all_interior_pointers) {
      GC_push_all(bottom, top);
    } else {
--- 1405,1409 ----
  ptr_t top;
  {
!   if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
      GC_push_all(bottom, top);
    } else {

Index: mark_rts.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/mark_rts.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** mark_rts.c  8 Apr 2002 23:36:50 -0000       1.2
--- mark_rts.c  6 Feb 2003 01:35:46 -0000       1.3
***************
*** 507,510 ****
--- 507,521 ----
  #endif
  
+ void GC_cond_register_dynamic_libraries()
+ {
+ # if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
+      || defined(PCR)) && !defined(SRC_M3)
+     GC_remove_tmp_roots();
+     if (!GC_no_dls) GC_register_dynamic_libraries();
+ # else
+     GC_no_dls = TRUE;
+ # endif
+ }
+ 
  /*
   * Call the mark routines (GC_tl_push for a single pointer, 
GC_push_conditional
***************
*** 520,524 ****
  ptr_t cold_gc_frame;
  {
!     register int i;
  
      /*
--- 531,536 ----
  ptr_t cold_gc_frame;
  {
!     int i;
!     int kind;
  
      /*
***************
*** 526,536 ****
       * not robust against mark stack overflow.
       */
!      /* Reregister dynamic libraries, in case one got added.  */
! #      if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
!          || defined(PCR)) && !defined(SRC_M3)
!          GC_remove_tmp_roots();
!          if (!GC_no_dls) GC_register_dynamic_libraries();
! #      else
!        GC_no_dls = TRUE;
  #      endif
  
--- 538,548 ----
       * not robust against mark stack overflow.
       */
!      /* Reregister dynamic libraries, in case one got added.          */
!      /* There is some argument for doing this as late as possible,    */
!      /* especially on win32, where it can change asynchronously.      */
!      /* In those cases, we do it here.  But on other platforms, it's  */
!      /* not safe with the world stopped, so we do it earlier.         */
! #      if !defined(REGISTER_LIBRARIES_EARLY)
!          GC_cond_register_dynamic_libraries();
  #      endif
  
***************
*** 542,545 ****
--- 554,569 ----
         }
  
+      /* Mark all free list header blocks, if those were allocated from        
*/
+      /* the garbage collected heap.  This makes sure they don't       */
+      /* disappear if we are not marking from static data.  It also    */
+      /* saves us the trouble of scanning them, and possibly that of   */
+      /* marking the freelists.                                                
*/
+        for (kind = 0; kind < GC_n_kinds; kind++) {
+        GC_PTR base = GC_base(GC_obj_kinds[kind].ok_freelist);
+        if (0 != base) {
+          GC_set_mark_bit(base);
+        }
+        }
+        
       /* Mark from GC internal roots if those might otherwise have     */
       /* been excluded.                                                        
*/

Index: misc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/misc.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** misc.c      8 May 2002 23:16:46 -0000       1.4
--- misc.c      6 Feb 2003 01:35:46 -0000       1.5
***************
*** 17,20 ****
--- 17,21 ----
  
  #include <stdio.h>
+ #include <limits.h>
  #ifndef _WIN32_WCE
  #include <signal.h>
***************
*** 31,37 ****
  # define NOSERVICE
  # include <windows.h>
! # if !defined(__CYGWIN32__) && !defined(__CYGWIN__)
! #  include <tchar.h>
! # endif
  #endif
  
--- 32,36 ----
  # define NOSERVICE
  # include <windows.h>
! # include <tchar.h>
  #endif
  
***************
*** 48,53 ****
          mutex_t GC_allocate_ml;       /* Implicitly initialized.      */
  #     else
! #          ifdef GC_WIN32_THREADS
! #           if !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL))
                 __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml;
  #           else
--- 47,54 ----
          mutex_t GC_allocate_ml;       /* Implicitly initialized.      */
  #     else
! #          if defined(GC_WIN32_THREADS) 
! #             if defined(GC_PTHREADS)
!                 pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER;
! #           elif !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL))
                 __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml;
  #           else
***************
*** 77,80 ****
--- 78,89 ----
  #endif
  
+ /* Dont unnecessarily call GC_register_main_static_data() in case     */
+ /* dyn_load.c isn't linked in.                                                
*/
+ #ifdef DYNAMIC_LOADING
+ # define GC_REGISTER_MAIN_STATIC_DATA() GC_register_main_static_data()
+ #else
+ # define GC_REGISTER_MAIN_STATIC_DATA() TRUE
+ #endif
+ 
  GC_FAR struct _GC_arrays GC_arrays /* = { 0 } */;
  
***************
*** 84,87 ****
--- 93,97 ----
  
  void (*GC_check_heap) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0;
+ void (*GC_print_all_smashed) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0;
  
  void (*GC_start_call_back) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0;
***************
*** 103,106 ****
--- 113,120 ----
  GC_bool GC_print_back_height = 0;
  
+ #ifndef NO_DEBUGGING
+   GC_bool GC_dump_regularly = 0;  /* Generate regular debugging dumps. */
+ #endif
+ 
  #ifdef FIND_LEAK
    int GC_find_leak = 1;
***************
*** 115,118 ****
--- 129,138 ----
  #endif
  
+ long GC_large_alloc_warn_interval = 5;
+       /* Interval between unsuppressed warnings.      */
+ 
+ long GC_large_alloc_warn_suppressed = 0;
+       /* Number of warnings suppressed so far.        */
+ 
  /*ARGSUSED*/
  GC_PTR GC_default_oom_fn GC_PROTO((size_t bytes_requested))
***************
*** 443,447 ****
      DISABLE_SIGNALS();
  
! #ifdef GC_WIN32_THREADS
      if (!GC_is_initialized) InitializeCriticalSection(&GC_allocate_ml);
  #endif /* MSWIN32 */
--- 463,467 ----
      DISABLE_SIGNALS();
  
! #if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
      if (!GC_is_initialized) InitializeCriticalSection(&GC_allocate_ml);
  #endif /* MSWIN32 */
***************
*** 486,492 ****
  
  #ifdef MSWIN32
!   extern GC_bool GC_is_win32s();
  #else
! # define GC_is_win32s() FALSE
  #endif
  
--- 506,521 ----
  
  #ifdef MSWIN32
! extern GC_bool GC_no_win32_dlls;
  #else
! # define GC_no_win32_dlls FALSE
! #endif
! 
! void GC_exit_check GC_PROTO((void))
! {
!    GC_gcollect();
! }
! 
! #ifdef SEARCH_FOR_DATA_START
!   extern void GC_init_linux_data_start GC_PROTO((void));
  #endif
  
***************
*** 502,510 ****
--- 531,550 ----
        GC_print_stats = 1;
  #   endif
+ #   if defined(MSWIN32) || defined(MSWINCE)
+       InitializeCriticalSection(&GC_write_cs);
+ #   endif
      if (0 != GETENV("GC_PRINT_STATS")) {
        GC_print_stats = 1;
      } 
+ #   ifndef NO_DEBUGGING
+       if (0 != GETENV("GC_DUMP_REGULARLY")) {
+         GC_dump_regularly = 1;
+       }
+ #   endif
      if (0 != GETENV("GC_FIND_LEAK")) {
        GC_find_leak = 1;
+ #     ifdef __STDC__
+         atexit(GC_exit_check);
+ #     endif
      }
      if (0 != GETENV("GC_ALL_INTERIOR_POINTERS")) {
***************
*** 517,525 ****
        GC_print_back_height = 1;
      }
      {
        char * time_limit_string = GETENV("GC_PAUSE_TIME_TARGET");
        if (0 != time_limit_string) {
!         long time_limit;
!         if (time_limit_string != 0) time_limit = atol(time_limit_string);
          if (time_limit < 5) {
          WARN("GC_PAUSE_TIME_TARGET environment variable value too small "
--- 557,567 ----
        GC_print_back_height = 1;
      }
+     if (0 != GETENV("GC_NO_BLACKLIST_WARNING")) {
+       GC_large_alloc_warn_interval = LONG_MAX;
+     }
      {
        char * time_limit_string = GETENV("GC_PAUSE_TIME_TARGET");
        if (0 != time_limit_string) {
!         long time_limit = atol(time_limit_string);
          if (time_limit < 5) {
          WARN("GC_PAUSE_TIME_TARGET environment variable value too small "
***************
*** 530,533 ****
--- 572,587 ----
        }
      }
+     {
+       char * interval_string = GETENV("GC_LARGE_ALLOC_WARN_INTERVAL");
+       if (0 != interval_string) {
+         long interval = atol(interval_string);
+         if (interval <= 0) {
+         WARN("GC_LARGE_ALLOC_WARN_INTERVAL environment variable has "
+              "bad value: Ignoring\n", 0);
+         } else {
+         GC_large_alloc_warn_interval = interval;
+         }
+       }
+     }
  #   ifdef UNIX_LIKE
        if (0 != GETENV("GC_LOOP_ON_ABORT")) {
***************
*** 539,545 ****
        GC_obj_kinds[NORMAL].ok_descriptor = ((word)(-ALIGNMENT) | 
GC_DS_LENGTH);
      }
- #   if defined(MSWIN32) || defined(MSWINCE)
-       InitializeCriticalSection(&GC_write_cs);
- #   endif
      GC_setpagesize();
      GC_exclude_static_roots(beginGC_arrays, endGC_arrays);
--- 593,596 ----
***************
*** 553,557 ****
  #   endif
  #   if defined(SEARCH_FOR_DATA_START)
!       GC_init_linux_data_start();
  #   endif
  #   if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
--- 604,608 ----
  #   endif
  #   if defined(SEARCH_FOR_DATA_START)
!       if (GC_REGISTER_MAIN_STATIC_DATA()) GC_init_linux_data_start();
  #   endif
  #   if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
***************
*** 572,575 ****
--- 623,636 ----
          GC_register_stackbottom = GC_get_register_stack_base();
  #       endif
+       } else {
+ #       if defined(LINUX) && defined(IA64)
+         if (GC_register_stackbottom == 0) {
+           WARN("GC_register_stackbottom should be set with GC_stackbottom", 
0);
+           /* The following is likely to fail, since we rely on        */
+           /* alignment properties that may not hold with a user set   */
+           /* GC_stackbottom.                                          */
+           GC_register_stackbottom = GC_get_register_stack_base();
+         }
+ #     endif
        }
  #   endif
***************
*** 600,604 ****
      /* Add initial guess of root sets.  Do this first, since sbrk(0)  */
      /* might be used.                                                 */
!       GC_register_data_segments();
      GC_init_headers();
      GC_bl_init();
--- 661,665 ----
      /* Add initial guess of root sets.  Do this first, since sbrk(0)  */
      /* might be used.                                                 */
!       if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments();
      GC_init_headers();
      GC_bl_init();
***************
*** 615,618 ****
--- 676,691 ----
        }
      }
+     {
+       char * sz_str = GETENV("GC_MAXIMUM_HEAP_SIZE");
+       if (sz_str != NULL) {
+         word max_heap_sz = (word)atol(sz_str);
+         if (max_heap_sz < initial_heap_sz * HBLKSIZE) {
+           WARN("Bad maximum heap size %s - ignoring it.\n",
+                sz_str);
+         } 
+         if (0 == GC_max_retries) GC_max_retries = 2;
+         GC_set_max_heap_size(max_heap_sz);
+       }
+     }
      if (!GC_expand_hp_inner(initial_heap_sz)) {
          GC_err_printf0("Can't start up: not enough memory\n");
***************
*** 640,644 ****
  #   endif
  #   if !defined(SMALL_CONFIG)
!       if (!GC_is_win32s() && 0 != GETENV("GC_ENABLE_INCREMENTAL")) {
        GC_ASSERT(!GC_incremental);
          GC_setpagesize();
--- 713,717 ----
  #   endif
  #   if !defined(SMALL_CONFIG)
!       if (!GC_no_win32_dlls && 0 != GETENV("GC_ENABLE_INCREMENTAL")) {
        GC_ASSERT(!GC_incremental);
          GC_setpagesize();
***************
*** 650,653 ****
--- 723,727 ----
        }
  #   endif /* !SMALL_CONFIG */
+     COND_DUMP;
      /* Get black list set up and/or incrmental GC started */
        if (!GC_dont_precollect || GC_incremental) GC_gcollect_inner();
***************
*** 684,688 ****
      if (GC_incremental) goto out;
      GC_setpagesize();
!     if (GC_is_win32s()) goto out;
  #   ifndef GC_SOLARIS_THREADS
          GC_dirty_init();
--- 758,762 ----
      if (GC_incremental) goto out;
      GC_setpagesize();
!     if (GC_no_win32_dlls) goto out;
  #   ifndef GC_SOLARIS_THREADS
          GC_dirty_init();
***************
*** 715,723 ****
  
  #if defined(MSWIN32) || defined(MSWINCE)
- #if defined(__CYGWIN32__) || defined(__CYGWIN__)
- # define LOG_FILE "gc.log"
- #else
  # define LOG_FILE _T("gc.log")
- #endif
  
    HANDLE GC_stdout = 0;
--- 789,793 ----
***************
*** 909,912 ****
--- 979,993 ----
  }
  
+ # if defined(__STDC__) || defined(__cplusplus)
+     GC_word GC_set_free_space_divisor (GC_word value)
+ # else
+     GC_word GC_set_free_space_divisor (value)
+     GC_word value;
+ # endif
+ {
+     GC_word old = GC_free_space_divisor;
+     GC_free_space_divisor = value;
+     return old;
+ }
  
  #ifndef PCR
***************
*** 935,1054 ****
  #endif
  
- #ifdef NEED_CALLINFO
- 
- #ifdef HAVE_BUILTIN_BACKTRACE
- # include <execinfo.h>
- # ifdef LINUX
- #   include <unistd.h>
- # endif
- #endif
- 
- void GC_print_callers (info)
- struct callinfo info[NFRAMES];
- {
-     register int i;
-     
- #   if NFRAMES == 1
-       GC_err_printf0("\tCaller at allocation:\n");
- #   else
-       GC_err_printf0("\tCall chain at allocation:\n");
- #   endif
-     for (i = 0; i < NFRAMES; i++) {
-       if (info[i].ci_pc == 0) break;
- #     if NARGS > 0
-       {
-         int j;
- 
-         GC_err_printf0("\t\targs: ");
-         for (j = 0; j < NARGS; j++) {
-           if (j != 0) GC_err_printf0(", ");
-           GC_err_printf2("%d (0x%X)", ~(info[i].ci_arg[j]),
-                                       ~(info[i].ci_arg[j]));
-         }
-         GC_err_printf0("\n");
-       }
- #     endif
- #     if defined(HAVE_BUILTIN_BACKTRACE) && !defined(REDIRECT_MALLOC)
-         /* Unfortunately backtrace_symbols calls malloc, which makes  */
-         /* it dangersous if that has been redirected.                 */
-         {
-           char **sym_name =
-             backtrace_symbols((void **)(&(info[i].ci_pc)), 1);
-           char *name = sym_name[0];
-           GC_bool found_it = (strchr(name, '(') != 0);
-           FILE *pipe;
- #         ifdef LINUX
-             if (!found_it) {
- #             define EXE_SZ 100
-               static char exe_name[EXE_SZ];
- #             define CMD_SZ 200
-               char cmd_buf[CMD_SZ];
- #             define RESULT_SZ 200
-               static char result_buf[RESULT_SZ];
-               size_t result_len;
-               static GC_bool found_exe_name = FALSE;
-               static GC_bool will_fail = FALSE;
-               int ret_code;
-               /* Unfortunately, this is the common case for the       */
-               /* main executable.                                     */
-               /* Try to get it via a hairy and expensive scheme.      */
-               /* First we get the name of the executable:             */
-               if (will_fail) goto out;
-               if (!found_exe_name) { 
-                 ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ);
-                 if (ret_code < 0 || ret_code >= EXE_SZ || exe_name[0] != '/') 
{
-                   will_fail = TRUE;   /* Dont try again. */
-                   goto out;
-                 }
-                 exe_name[ret_code] = '\0';
-                 found_exe_name = TRUE;
-               }
-               /* Then we use popen to start addr2line -e <exe> <addr> */
-               /* There are faster ways to do this, but hopefully this */
-               /* isn't time critical.                                 */
-               sprintf(cmd_buf, "/usr/bin/addr2line -e %s 0x%lx", exe_name,
-                                (unsigned long)info[i].ci_pc);
-               pipe = popen(cmd_buf, "r");
-               if (pipe < 0 || fgets(result_buf, RESULT_SZ, pipe) == 0) {
-                 will_fail = TRUE;
-                 goto out;
-               }
-               result_len = strlen(result_buf);
-               if (result_buf[result_len - 1] == '\n') --result_len;
-               if (result_buf[0] == '?'
-                   || result_buf[result_len-2] == ':' 
-                      && result_buf[result_len-1] == '0')
-                   goto out;
-               if (result_len < RESULT_SZ - 25) {
-                 /* Add in hex address */
-                   sprintf(result_buf + result_len, " [0x%lx]",
-                         (unsigned long)info[i].ci_pc);
-               }
-               name = result_buf;
-               pclose(pipe);
-               out:
-             }
- #         endif
-           GC_err_printf1("\t\t%s\n", name);
-           free(sym_name);
-         }
- #     else
-         GC_err_printf1("\t\t##PC##= 0x%lx\n", info[i].ci_pc);
- #     endif
-     }
- }
- 
- #endif /* SAVE_CALL_CHAIN */
- 
- /* Needed by SRC_M3, gcj, and should perhaps be the official interface        
*/
- /* to GC_dont_gc.                                                     */
  void GC_enable()
  {
      GC_dont_gc--;
  }
  
  void GC_disable()
  {
      GC_dont_gc++;
  }
  
--- 1016,1031 ----
  #endif
  
  void GC_enable()
  {
+     LOCK();
      GC_dont_gc--;
+     UNLOCK();
  }
  
  void GC_disable()
  {
+     LOCK();
      GC_dont_gc++;
+     UNLOCK();
  }
  
***************
*** 1065,1068 ****
--- 1042,1047 ----
      GC_printf0("\n***Blocks in use:\n");
      GC_print_block_list();
+     GC_printf0("\n***Finalization statistics:\n");
+     GC_print_finalization_stats();
  }
  

Index: mkinstalldirs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/mkinstalldirs,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** mkinstalldirs       9 Nov 2001 02:21:15 -0000       1.1.1.1
--- mkinstalldirs       6 Feb 2003 01:35:46 -0000       1.2
***************
*** 3,17 ****
  # Author: Noah Friedman <address@hidden>
  # Created: 1993-05-16
- # Last modified: 1994-03-25
  # Public domain
  
  errstatus=0
  
! for file in ${1+"$@"} ; do 
     set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
     shift
  
     pathcomp=
!    for d in ${1+"$@"} ; do
       pathcomp="$pathcomp$d"
       case "$pathcomp" in
--- 3,66 ----
  # Author: Noah Friedman <address@hidden>
  # Created: 1993-05-16
  # Public domain
  
+ # $Id$
+ 
  errstatus=0
+ dirmode=""
+ 
+ usage="\
+ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+ 
+ # process command line arguments
+ while test $# -gt 0 ; do
+    case "${1}" in
+      -h | --help | --h* )                     # -h for help
+       echo "${usage}" 1>&2; exit 0 ;;
+      -m )                                     # -m PERM arg
+       shift
+       test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
+       dirmode="${1}"
+       shift ;;
+      -- ) shift; break ;;                     # stop option processing
+      -* ) echo "${usage}" 1>&2; exit 1 ;;     # unknown option
+      * )  break ;;                            # first non-opt arg
+    esac
+ done
+ 
+ for file
+ do
+   if test -d "$file"; then
+     shift
+   else
+     break
+   fi
+ done
+ 
+ case $# in
+ 0) exit 0 ;;
+ esac
+ 
+ case $dirmode in
+ '')
+   if mkdir -p -- . 2>/dev/null; then
+     echo "mkdir -p -- $*"
+     exec mkdir -p -- "$@"
+   fi ;;
+ *)
+   if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+     echo "mkdir -m $dirmode -p -- $*"
+     exec mkdir -m "$dirmode" -p -- "$@"
+   fi ;;
+ esac
  
! for file
! do
     set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
     shift
  
     pathcomp=
!    for d
!    do
       pathcomp="$pathcomp$d"
       case "$pathcomp" in
***************
*** 20,29 ****
  
       if test ! -d "$pathcomp"; then
!         echo "mkdir $pathcomp" 1>&2
!         mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
!      fi
  
!      if test ! -d "$pathcomp"; then
!       errstatus=$lasterr
       fi
  
--- 69,90 ----
  
       if test ! -d "$pathcomp"; then
!       echo "mkdir $pathcomp"
  
!       mkdir "$pathcomp" || lasterr=$?
! 
!       if test ! -d "$pathcomp"; then
!         errstatus=$lasterr
!       else
!         if test ! -z "$dirmode"; then
!            echo "chmod $dirmode $pathcomp"
! 
!            lasterr=""
!            chmod "$dirmode" "$pathcomp" || lasterr=$?
! 
!            if test ! -z "$lasterr"; then
!              errstatus=$lasterr
!            fi
!         fi
!       fi
       fi
  
***************
*** 34,36 ****
--- 95,101 ----
  exit $errstatus
  
+ # Local Variables:
+ # mode: shell-script
+ # sh-indentation: 3
+ # End:
  # mkinstalldirs ends here

Index: os_dep.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/os_dep.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** os_dep.c    8 Apr 2002 23:36:50 -0000       1.2
--- os_dep.c    6 Feb 2003 01:35:46 -0000       1.3
***************
*** 81,90 ****
  # endif
  
! #ifdef NEED_FIND_LIMIT
! #   include <setjmp.h>
  #endif
  
! #ifdef FREEBSD
! #  include <machine/trap.h>
  #endif
  
--- 81,93 ----
  # endif
  
! #if defined(FREEBSD) && defined(I386)
! #  include <machine/trap.h>
! #  if !defined(PCR)
! #    define NEED_FIND_LIMIT
! #  endif
  #endif
  
! #ifdef NEED_FIND_LIMIT
! #   include <setjmp.h>
  #endif
  
***************
*** 155,164 ****
  
  # ifdef LINUX
  #   pragma weak __data_start
!     extern int __data_start;
  #   pragma weak data_start
!     extern int data_start;
  # endif /* LINUX */
!   extern int _end;
  
    ptr_t GC_data_start;
--- 158,172 ----
  
  # ifdef LINUX
+     /* Some Linux distributions arrange to define __data_start.  Some */
+     /* define data_start as a weak symbol.  The latter is technically */
+     /* broken, since the user program may define data_start, in which */
+     /* case we lose.  Nonetheless, we try both, prefering __data_start.       
*/
+     /* We assume gcc-compatible pragmas.      */
  #   pragma weak __data_start
!     extern int __data_start[];
  #   pragma weak data_start
!     extern int data_start[];
  # endif /* LINUX */
!   extern int _end[];
  
    ptr_t GC_data_start;
***************
*** 170,183 ****
  #   ifdef LINUX
        /* Try the easy approaches first:       */
!       if (&__data_start != 0) {
!         GC_data_start = (ptr_t)(&__data_start);
          return;
        }
!       if (&data_start != 0) {
!         GC_data_start = (ptr_t)(&data_start);
          return;
        }
  #   endif /* LINUX */
!     GC_data_start = GC_find_limit((ptr_t)(&_end), FALSE);
    }
  #endif
--- 178,191 ----
  #   ifdef LINUX
        /* Try the easy approaches first:       */
!       if ((ptr_t)__data_start != 0) {
!         GC_data_start = (ptr_t)(__data_start);
          return;
        }
!       if ((ptr_t)data_start != 0) {
!         GC_data_start = (ptr_t)(data_start);
          return;
        }
  #   endif /* LINUX */
!     GC_data_start = GC_find_limit((ptr_t)(_end), FALSE);
    }
  #endif
***************
*** 618,622 ****
  
      /* Return the first nonaddressible location > p (up) or   */
!     /* the smallest location q s.t. [q,p] is addressible (!up).       */
      ptr_t GC_find_limit(p, up)
      ptr_t p;
--- 626,631 ----
  
      /* Return the first nonaddressible location > p (up) or   */
!     /* the smallest location q s.t. [q,p) is addressable (!up).       */
!     /* We assume that p (up) or p-1 (!up) is addressable.     */
      ptr_t GC_find_limit(p, up)
      ptr_t p;
***************
*** 662,665 ****
--- 671,675 ----
  #include <sys/types.h>
  #include <sys/stat.h>
+ #include <ctype.h>
  
  # define STAT_SKIP 27   /* Number of fields preceding startstack      */
***************
*** 756,767 ****
    ptr_t GC_freebsd_stack_base(void)
    {
!     int nm[2] = { CTL_KERN, KERN_USRSTACK}, base, len, r;
!     
!     len = sizeof(int);
!     r = sysctl(nm, 2, &base, &len, NULL, 0);
      
      if (r) ABORT("Error getting stack base");
  
!     return (ptr_t)base;
    }
  
--- 766,777 ----
    ptr_t GC_freebsd_stack_base(void)
    {
!     int nm[2] = {CTL_KERN, KERN_USRSTACK};
!     ptr_t base;
!     size_t len = sizeof(ptr_t);
!     int r = sysctl(nm, 2, &base, &len, NULL, 0);
      
      if (r) ABORT("Error getting stack base");
  
!     return base;
    }
  
***************
*** 932,952 ****
    /* Since VirtualQuery has very different semantics.  In particular, */
    /* under win32s a VirtualQuery call on an unmapped page returns an  */
!   /* invalid result.  Under GC_register_data_segments is a noop and   */
    /* all real work is done by GC_register_dynamic_libraries.  Under   */
    /* win32s, we cannot find the data segments associated with dll's.  */
!   /* We rgister the main data segment here.                           */
!   GC_bool GC_win32s = FALSE;  /* We're running under win32s.  */
!   
!   GC_bool GC_is_win32s()
!   {
!       DWORD v = GetVersion();
!       
!       /* Check that this is not NT, and Windows major version <= 3    */
!       return ((v & 0x80000000) && (v & 0xff) <= 3);
!   }
    
    void GC_init_win32()
    {
!       GC_win32s = GC_is_win32s();
    }
  
--- 942,961 ----
    /* Since VirtualQuery has very different semantics.  In particular, */
    /* under win32s a VirtualQuery call on an unmapped page returns an  */
!   /* invalid result.  Under NT, GC_register_data_segments is a noop and       
*/
    /* all real work is done by GC_register_dynamic_libraries.  Under   */
    /* win32s, we cannot find the data segments associated with dll's.  */
!   /* We register the main data segment here.                          */
! #  ifdef __GCC__
!   GC_bool GC_no_win32_dlls = TRUE;
!                        /* GCC can't do SEH, so we can't use VirtualQuery */
! #  else
!   GC_bool GC_no_win32_dlls = FALSE;    
! #  endif
    
    void GC_init_win32()
    {
!     /* if we're running under win32s, assume that no DLLs will be loaded */
!     DWORD v = GetVersion();
!     GC_no_win32_dlls |= ((v & 0x80000000) && (v & 0xff) <= 3);
    }
  
***************
*** 974,977 ****
--- 983,1060 ----
    }
  # endif
+ 
+ # ifndef REDIRECT_MALLOC
+   /* We maintain a linked list of AllocationBase values that we know  */
+   /* correspond to malloc heap sections.  Currently this is only called */
+   /* during a GC.  But there is some hope that for long running               
*/
+   /* programs we will eventually see most heap sections.              */
+ 
+   /* In the long run, it would be more reliable to occasionally walk  */
+   /* the malloc heap with HeapWalk on the default heap.  But that     */
+   /* apparently works only for NT-based Windows.                      */ 
+ 
+   /* In the long run, a better data structure would also be nice ...  */
+   struct GC_malloc_heap_list {
+     void * allocation_base;
+     struct GC_malloc_heap_list *next;
+   } *GC_malloc_heap_l = 0;
+ 
+   /* Is p the base of one of the malloc heap sections we already know */
+   /* about?                                                           */
+   GC_bool GC_is_malloc_heap_base(ptr_t p)
+   {
+     struct GC_malloc_heap_list *q = GC_malloc_heap_l;
+ 
+     while (0 != q) {
+       if (q -> allocation_base == p) return TRUE;
+       q = q -> next;
+     }
+     return FALSE;
+   }
+ 
+   void *GC_get_allocation_base(void *p)
+   {
+     MEMORY_BASIC_INFORMATION buf;
+     DWORD result = VirtualQuery(p, &buf, sizeof(buf));
+     if (result != sizeof(buf)) {
+       ABORT("Weird VirtualQuery result");
+     }
+     return buf.AllocationBase;
+   }
+ 
+   size_t GC_max_root_size = 100000;   /* Appr. largest root size.     */
+ 
+   void GC_add_current_malloc_heap()
+   {
+     struct GC_malloc_heap_list *new_l =
+                  malloc(sizeof(struct GC_malloc_heap_list));
+     void * candidate = GC_get_allocation_base(new_l);
+ 
+     if (new_l == 0) return;
+     if (GC_is_malloc_heap_base(candidate)) {
+       /* Try a little harder to find malloc heap.                     */
+       size_t req_size = 10000;
+       do {
+         void *p = malloc(req_size);
+         if (0 == p) { free(new_l); return; }
+         candidate = GC_get_allocation_base(p);
+         free(p);
+         req_size *= 2;
+       } while (GC_is_malloc_heap_base(candidate)
+                && req_size < GC_max_root_size/10 && req_size < 500000);
+       if (GC_is_malloc_heap_base(candidate)) {
+         free(new_l); return;
+       }
+     }
+ #   ifdef CONDPRINT
+       if (GC_print_stats)
+         GC_printf1("Found new system malloc AllocationBase at 0x%lx\n",
+                      candidate);
+ #   endif
+     new_l -> allocation_base = candidate;
+     new_l -> next = GC_malloc_heap_l;
+     GC_malloc_heap_l = new_l;
+   }
+ # endif /* REDIRECT_MALLOC */
    
    /* Is p the start of either the malloc heap, or of one of our */
***************
*** 980,1007 ****
    {
       
!      register unsigned i;
       
  #    ifndef REDIRECT_MALLOC
!        static ptr_t malloc_heap_pointer = 0;
       
!        if (0 == malloc_heap_pointer) {
!          MEMORY_BASIC_INFORMATION buf;
!          void *pTemp = malloc( 1 );
!          register DWORD result = VirtualQuery(pTemp, &buf, sizeof(buf));
!            
!          free( pTemp );
! 
!          
!          if (result != sizeof(buf)) {
!              ABORT("Weird VirtualQuery result");
!          }
!          malloc_heap_pointer = (ptr_t)(buf.AllocationBase);
         }
!        if (p == malloc_heap_pointer) return(TRUE);
  #    endif
       for (i = 0; i < GC_n_heap_bases; i++) {
!          if (GC_heap_bases[i] == p) return(TRUE);
       }
!      return(FALSE);
    }
  
--- 1063,1082 ----
    {
       
!      unsigned i;
       
  #    ifndef REDIRECT_MALLOC
!        static word last_gc_no = -1;
       
!        if (last_gc_no != GC_gc_no) {
!        GC_add_current_malloc_heap();
!        last_gc_no = GC_gc_no;
         }
!        if (GC_root_size > GC_max_root_size) GC_max_root_size = GC_root_size;
!        if (GC_is_malloc_heap_base(p)) return TRUE;
  #    endif
       for (i = 0; i < GC_n_heap_bases; i++) {
!          if (GC_heap_bases[i] == p) return TRUE;
       }
!      return FALSE ;
    }
  
***************
*** 1016,1020 ****
        char * limit, * new_limit;
      
!       if (!GC_win32s) return;
        p = base = limit = GC_least_described_address(static_root);
        while (p < GC_sysinfo.lpMaximumApplicationAddress) {
--- 1091,1095 ----
        char * limit, * new_limit;
      
!       if (!GC_no_win32_dlls) return;
        p = base = limit = GC_least_described_address(static_root);
        while (p < GC_sysinfo.lpMaximumApplicationAddress) {
***************
*** 1053,1057 ****
  # if (defined(SVR4) || defined(AUX) || defined(DGUX) \
        || (defined(LINUX) && defined(SPARC))) && !defined(PCR)
! char * GC_SysVGetDataStart(max_page_size, etext_addr)
  int max_page_size;
  int * etext_addr;
--- 1128,1132 ----
  # if (defined(SVR4) || defined(AUX) || defined(DGUX) \
        || (defined(LINUX) && defined(SPARC))) && !defined(PCR)
! ptr_t GC_SysVGetDataStart(max_page_size, etext_addr)
  int max_page_size;
  int * etext_addr;
***************
*** 1079,1086 ****
        /* Use plan B.  Note that we now know there is a gap between    */
        /* text and data segments, so plan A bought us something.       */
!       result = (char *)GC_find_limit((ptr_t)(DATAEND) - MIN_PAGE_SIZE, FALSE);
      }
!     return((char *)result);
  }
  # endif
  
--- 1154,1194 ----
        /* Use plan B.  Note that we now know there is a gap between    */
        /* text and data segments, so plan A bought us something.       */
!       result = (char *)GC_find_limit((ptr_t)(DATAEND), FALSE);
!     }
!     return((ptr_t)result);
! }
! # endif
! 
! # if defined(FREEBSD) && defined(I386) && !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   */
! /* etext.  But in some cases there actually seems to be slightly more.  */
! /* This also deals with holes between read-only data and writable data.       
*/
! ptr_t GC_FreeBSDGetDataStart(max_page_size, etext_addr)
! int max_page_size;
! int * etext_addr;
! {
!     word text_end = ((word)(etext_addr) + sizeof(word) - 1)
!                    & ~(sizeof(word) - 1);
!       /* etext rounded to word boundary       */
!     VOLATILE word next_page = (text_end + (word)max_page_size - 1)
!                             & ~((word)max_page_size - 1);
!     VOLATILE ptr_t result = (ptr_t)text_end;
!     GC_setup_temporary_fault_handler();
!     if (setjmp(GC_jmp_buf) == 0) {
!       /* Try reading at the address.                          */
!       /* This should happen before there is another thread.   */
!       for (; next_page < (word)(DATAEND); next_page += (word)max_page_size)
!           *(VOLATILE char *)next_page;
!       GC_reset_fault_handler();
!     } else {
!       GC_reset_fault_handler();
!       /* As above, we go to plan B    */
!       result = GC_find_limit((ptr_t)(DATAEND), FALSE);
      }
!     return(result);
  }
+ 
  # endif
  
***************
*** 1096,1101 ****
  void GC_register_data_segments()
  {
! #   if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) 
\
!        && !defined(MACOSX)
  #     if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
        /* As of Solaris 2.3, the Solaris threads implementation        */
--- 1204,1208 ----
  void GC_register_data_segments()
  {
! #   if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS)
  #     if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
        /* As of Solaris 2.3, the Solaris threads implementation        */
***************
*** 1114,1120 ****
  #     endif
  #   endif
- #   if !defined(PCR) && (defined(NEXT) || defined(MACOSX))
-       GC_add_roots_inner(DATASTART, (char *) get_end(), FALSE);
- #   endif
  #   if defined(MACOS)
      {
--- 1221,1224 ----
***************
*** 1233,1236 ****
--- 1337,1341 ----
      if (!initialized) {
        fd = open("/dev/zero", O_RDONLY);
+       fcntl(fd, F_SETFD, FD_CLOEXEC);
        initialized = TRUE;
      }
***************
*** 1238,1248 ****
      result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
                  GC_MMAP_FLAGS, fd, 0/* offset */);
- #   if defined(LINUX) && defined(I386)
-       if (result == MAP_FAILED) {
-       /* Retry with a bit of encouragement to use low addresses as well. */
-       result = mmap(0x1000, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
-                 GC_MMAP_FLAGS, fd, 0/* offset */);
-       }
- #   endif
      if (result == MAP_FAILED) return(0);
      last_addr = (ptr_t)result + bytes + GC_page_size - 1;
--- 1343,1346 ----
***************
*** 1322,1326 ****
  #   define GLOBAL_ALLOC_TEST 1
  # else
! #   define GLOBAL_ALLOC_TEST GC_win32s
  # endif
  
--- 1420,1424 ----
  #   define GLOBAL_ALLOC_TEST 1
  # else
! #   define GLOBAL_ALLOC_TEST GC_no_win32_dlls
  # endif
  
***************
*** 1361,1365 ****
  void GC_win32_free_heap ()
  {
!     if (GC_win32s) {
        while (GC_n_heap_bases > 0) {
            GlobalFree (GC_heap_bases[--GC_n_heap_bases]);
--- 1459,1463 ----
  void GC_win32_free_heap ()
  {
!     if (GC_no_win32_dlls) {
        while (GC_n_heap_bases > 0) {
            GlobalFree (GC_heap_bases[--GC_n_heap_bases]);
***************
*** 1537,1540 ****
--- 1635,1639 ----
  #   else
        if (-1 == zero_descr) zero_descr = open("/dev/zero", O_RDWR);
+       fcntl(zero_descr, F_SETFD, FD_CLOEXEC);
        if (0 == start_addr) return;
        result = mmap(start_addr, len, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
***************
*** 1900,1904 ****
  #   else  /* glibc < 2.2 */
  #     include <linux/version.h>
! #     if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA)
          typedef struct sigcontext s_c;
  #     else
--- 1999,2003 ----
  #   else  /* glibc < 2.2 */
  #     include <linux/version.h>
! #     if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA) 
|| defined(ARM32)
          typedef struct sigcontext s_c;
  #     else
***************
*** 2148,2152 ****
          void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
  #     else
!         void GC_write_fault_handler(int sig, s_c sc)
  #     endif
  #   endif
--- 2247,2255 ----
          void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
  #     else
! #       if defined(ARM32)
!           void GC_write_fault_handler(int sig, int a2, int a3, int a4, s_c sc)
! #       else
!           void GC_write_fault_handler(int sig, s_c sc)
! #       endif
  #     endif
  #   endif
***************
*** 2207,2211 ****
  #   endif
  #   ifdef LINUX
! #     ifdef I386
        char * addr = (char *) (sc.cr2);
  #     else
--- 2310,2314 ----
  #   endif
  #   ifdef LINUX
! #     if defined(I386) || defined (X86_64)
        char * addr = (char *) (sc.cr2);
  #     else
***************
*** 2251,2255 ****
                  char * addr = (char *) (sc.regs->dar);
  #           else
!               --> architecture not supported
  #           endif
  #         endif
--- 2354,2362 ----
                  char * addr = (char *) (sc.regs->dar);
  #           else
! #               if defined(ARM32)
!                   char * addr = (char *)sc.fault_address;
! #               else
!                 --> architecture not supported
! #               endif
  #           endif
  #         endif
***************
*** 2849,2852 ****
--- 2956,2960 ----
      GC_proc_fd = syscall(SYS_ioctl, fd, PIOCOPENPD, 0);
      close(fd);
+     syscall(SYS_fcntl, GC_proc_fd, F_SETFD, FD_CLOEXEC);
      if (GC_proc_fd < 0) {
        ABORT("/proc ioctl failed");
***************
*** 3148,3164 ****
  #endif /* SPARC */
  
! #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.                    */
  
  #ifdef LINUX
! # include <features.h>
! # if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2
! #   define HAVE_BUILTIN_BACKTRACE
! # endif
  #endif
  
  #if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \
!     && defined(HAVE_BUILTIN_BACKTRACE)
  
  #include <execinfo.h>
--- 3256,3273 ----
  #endif /* SPARC */
  
! #ifdef  NEED_CALLINFO
  /* Fill in the pc and argument information for up to NFRAMES of my    */
  /* callers.  Ignore my frame and my callers frame.                    */
  
  #ifdef LINUX
! #   include <unistd.h>
  #endif
  
+ #endif /* NEED_CALLINFO */
+ 
+ #ifdef SAVE_CALL_CHAIN
+ 
  #if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \
!     && defined(GC_HAVE_BUILTIN_BACKTRACE)
  
  #include <execinfo.h>
***************
*** 3231,3234 ****
--- 3340,3476 ----
  #endif /* SAVE_CALL_CHAIN */
  
+ #ifdef NEED_CALLINFO
+ 
+ /* Print info to stderr.  We do NOT hold the allocation lock */
+ void GC_print_callers (info)
+ struct callinfo info[NFRAMES];
+ {
+     register int i;
+     static int reentry_count = 0;
+     GC_bool stop = FALSE;
+ 
+     LOCK();
+       ++reentry_count;
+     UNLOCK();
+     
+ #   if NFRAMES == 1
+       GC_err_printf0("\tCaller at allocation:\n");
+ #   else
+       GC_err_printf0("\tCall chain at allocation:\n");
+ #   endif
+     for (i = 0; i < NFRAMES && !stop ; i++) {
+       if (info[i].ci_pc == 0) break;
+ #     if NARGS > 0
+       {
+         int j;
+ 
+         GC_err_printf0("\t\targs: ");
+         for (j = 0; j < NARGS; j++) {
+           if (j != 0) GC_err_printf0(", ");
+           GC_err_printf2("%d (0x%X)", ~(info[i].ci_arg[j]),
+                                       ~(info[i].ci_arg[j]));
+         }
+         GC_err_printf0("\n");
+       }
+ #     endif
+         if (reentry_count > 1) {
+           /* We were called during an allocation during       */
+           /* a previous GC_print_callers call; punt.          */
+           GC_err_printf1("\t\t##PC##= 0x%lx\n", info[i].ci_pc);
+           continue;
+       }
+       {
+ #       ifdef LINUX
+           FILE *pipe;
+ #       endif
+ #       if defined(GC_HAVE_BUILTIN_BACKTRACE)
+           char **sym_name =
+             backtrace_symbols((void **)(&(info[i].ci_pc)), 1);
+           char *name = sym_name[0];
+ #       else
+           char buf[40];
+           char *name = buf;
+           sprintf(buf, "##PC##= 0x%lx", info[i].ci_pc);
+ #       endif
+ #       if defined(LINUX) && !defined(SMALL_CONFIG)
+           /* Try for a line number. */
+           {
+ #             define EXE_SZ 100
+               static char exe_name[EXE_SZ];
+ #             define CMD_SZ 200
+               char cmd_buf[CMD_SZ];
+ #             define RESULT_SZ 200
+               static char result_buf[RESULT_SZ];
+               size_t result_len;
+               static GC_bool found_exe_name = FALSE;
+               static GC_bool will_fail = FALSE;
+               int ret_code;
+               /* Try to get it via a hairy and expensive scheme.      */
+               /* First we get the name of the executable:             */
+               if (will_fail) goto out;
+               if (!found_exe_name) { 
+                 ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ);
+                 if (ret_code < 0 || ret_code >= EXE_SZ
+                     || exe_name[0] != '/') {
+                   will_fail = TRUE;   /* Dont try again. */
+                   goto out;
+                 }
+                 exe_name[ret_code] = '\0';
+                 found_exe_name = TRUE;
+               }
+               /* Then we use popen to start addr2line -e <exe> <addr> */
+               /* There are faster ways to do this, but hopefully this */
+               /* isn't time critical.                                 */
+               sprintf(cmd_buf, "/usr/bin/addr2line -f -e %s 0x%lx", exe_name,
+                                (unsigned long)info[i].ci_pc);
+               pipe = popen(cmd_buf, "r");
+               if (pipe == NULL
+                   || (result_len = fread(result_buf, 1, RESULT_SZ - 1, pipe))
+                      == 0) {
+                 if (pipe != NULL) pclose(pipe);
+                 will_fail = TRUE;
+                 goto out;
+               }
+               if (result_buf[result_len - 1] == '\n') --result_len;
+               result_buf[result_len] = 0;
+               if (result_buf[0] == '?'
+                   || result_buf[result_len-2] == ':' 
+                      && result_buf[result_len-1] == '0') {
+                   pclose(pipe);
+                   goto out;
+               }
+               /* Get rid of embedded newline, if any.  Test for "main" */
+               {
+                  char * nl = strchr(result_buf, '\n');
+                  if (nl != NULL && nl < result_buf + result_len) {
+                    *nl = ':';
+                  }
+                  if (strncmp(result_buf, "main", nl - result_buf) == 0) {
+                    stop = TRUE;
+                  }
+               }
+               if (result_len < RESULT_SZ - 25) {
+                 /* Add in hex address */
+                   sprintf(result_buf + result_len, " [0x%lx]",
+                         (unsigned long)info[i].ci_pc);
+               }
+               name = result_buf;
+               pclose(pipe);
+               out:
+           }
+ #       endif /* LINUX */
+         GC_err_printf1("\t\t%s\n", name);
+ #       if defined(GC_HAVE_BUILTIN_BACKTRACE)
+           free(sym_name);  /* May call GC_free; that's OK */
+ #         endif
+       }
+     }
+     LOCK();
+       --reentry_count;
+     UNLOCK();
+ }
+ 
+ #endif /* NEED_CALLINFO */
+ 
  #if defined(LINUX) && defined(__ELF__) && \
      (!defined(SMALL_CONFIG) || defined(USE_PROC_FOR_LIBRARIES))
***************
*** 3276,3280 ****
            GC_err_write(maps_temp, result);
        } while (result == sizeof(maps_temp));
!      
      GC_err_printf0("---------- End address map ----------\n");
  }
--- 3518,3522 ----
            GC_err_write(maps_temp, result);
        } while (result == sizeof(maps_temp));
!       close(f);     
      GC_err_printf0("---------- End address map ----------\n");
  }

Index: reclaim.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/reclaim.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** reclaim.c   8 Apr 2002 23:36:50 -0000       1.2
--- reclaim.c   6 Feb 2003 01:35:46 -0000       1.3
***************
*** 28,48 ****
  #endif /* PARALLEL_MARK */
  
! static void report_leak(p, sz)
! ptr_t p;
! word sz;
  {
!     if (HDR(p) -> hb_obj_kind == PTRFREE) {
!         GC_err_printf0("Leaked atomic object at ");
!     } else {
!         GC_err_printf0("Leaked composite object at ");
      }
!     GC_print_heap_obj(p);
!     GC_err_printf0("\n");
  }
  
  #   define FOUND_FREE(hblk, word_no) \
        { \
!          report_leak((ptr_t)hblk + WORDS_TO_BYTES(word_no), \
!                    HDR(hblk) -> hb_sz); \
        }
  
--- 28,86 ----
  #endif /* PARALLEL_MARK */
  
! /* We defer printing of leaked objects until we're done with the GC   */
! /* cycle, since the routine for printing objects needs to run outside */
! /* the collector, e.g. without the allocation lock.                   */
! #define MAX_LEAKED 40
! ptr_t GC_leaked[MAX_LEAKED];
! unsigned GC_n_leaked = 0;
! 
! GC_bool GC_have_errors = FALSE;
! 
! void GC_add_leaked(leaked)
! ptr_t leaked;
! {
!     if (GC_n_leaked < MAX_LEAKED) {
!       GC_have_errors = TRUE;
!       GC_leaked[GC_n_leaked++] = leaked;
!       /* Make sure it's not reclaimed this cycle */
!         GC_set_mark_bit(leaked);
!     }
! }
! 
! static GC_bool printing_errors = FALSE;
! /* Print all objects on the list after printing any smashed objs.     */
! /* Clear both lists.                                                  */
! void GC_print_all_errors ()
  {
!     unsigned i;
! 
!     LOCK();
!     if (printing_errors) {
!       UNLOCK();
!       return;
!     }
!     printing_errors = TRUE;
!     UNLOCK();
!     if (GC_debugging_started) GC_print_all_smashed();
!     for (i = 0; i < GC_n_leaked; ++i) {
!       ptr_t p = GC_leaked[i];
!       if (HDR(p) -> hb_obj_kind == PTRFREE) {
!           GC_err_printf0("Leaked atomic object at ");
!       } else {
!           GC_err_printf0("Leaked composite object at ");
!       }
!       GC_print_heap_obj(p);
!       GC_err_printf0("\n");
!       GC_free(p);
!       GC_leaked[i] = 0;
      }
!     GC_n_leaked = 0;
!     printing_errors = FALSE;
  }
  
+ 
  #   define FOUND_FREE(hblk, word_no) \
        { \
!          GC_add_leaked((ptr_t)hblk + WORDS_TO_BYTES(word_no)); \
        }
  
***************
*** 863,866 ****
--- 901,923 ----
  
  /*
+  * Clear all obj_link pointers in the list of free objects *flp.
+  * Clear *flp.
+  * This must be done before dropping a list of free gcj-style objects,
+  * since may otherwise end up with dangling "descriptor" pointers.
+  * It may help for other pointer-containg objects.
+  */
+ void GC_clear_fl_links(flp)
+ ptr_t *flp;
+ {
+     ptr_t next = *flp;
+ 
+     while (0 != next) {
+        *flp = 0;
+        flp = &(obj_link(next));
+        next = *flp;
+     }
+ }
+ 
+ /*
   * Perform GC_reclaim_block on the entire heap, after first clearing
   * small object free lists (if we are not just looking for leaks).
***************
*** 876,884 ****
      /* Clear reclaim- and free-lists */
        for (kind = 0; kind < GC_n_kinds; kind++) {
!         register ptr_t *fop;
!         register ptr_t *lim;
!         register struct hblk ** rlp;
!         register struct hblk ** rlim;
!         register struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list;
          
          if (rlist == 0) continue;     /* This kind not used.  */
--- 933,942 ----
      /* Clear reclaim- and free-lists */
        for (kind = 0; kind < GC_n_kinds; kind++) {
!         ptr_t *fop;
!         ptr_t *lim;
!         struct hblk ** rlp;
!         struct hblk ** rlim;
!         struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list;
!       GC_bool should_clobber = (GC_obj_kinds[kind].ok_descriptor != 0);
          
          if (rlist == 0) continue;     /* This kind not used.  */
***************
*** 886,890 ****
              lim = &(GC_obj_kinds[kind].ok_freelist[MAXOBJSZ+1]);
            for( fop = GC_obj_kinds[kind].ok_freelist; fop < lim; fop++ ) {
!             *fop = 0;
            }
        } /* otherwise free list objects are marked,    */
--- 944,954 ----
              lim = &(GC_obj_kinds[kind].ok_freelist[MAXOBJSZ+1]);
            for( fop = GC_obj_kinds[kind].ok_freelist; fop < lim; fop++ ) {
!             if (*fop != 0) {
!               if (should_clobber) {
!                 GC_clear_fl_links(fop);
!               } else {
!                 *fop = 0;
!               }
!             }
            }
        } /* otherwise free list objects are marked,    */

Index: solaris_threads.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/solaris_threads.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** solaris_threads.c   8 Apr 2002 23:36:50 -0000       1.2
--- solaris_threads.c   6 Feb 2003 01:35:46 -0000       1.3
***************
*** 826,830 ****
        t = GC_lookup_thread(target_thread);
        if (t == 0) ABORT("thread unknown to GC");
!         t -> flags |= SUSPENDED;
      }
      UNLOCK();
--- 826,830 ----
        t = GC_lookup_thread(target_thread);
        if (t == 0) ABORT("thread unknown to GC");
!         t -> flags |= SUSPNDED;
      }
      UNLOCK();
***************
*** 842,846 ****
        t = GC_lookup_thread(target_thread);
        if (t == 0) ABORT("thread unknown to GC");
!         t -> flags &= ~SUSPENDED;
      }
      UNLOCK();
--- 842,846 ----
        t = GC_lookup_thread(target_thread);
        if (t == 0) ABORT("thread unknown to GC");
!         t -> flags &= ~SUSPNDED;
      }
      UNLOCK();
***************
*** 928,932 ****
      }
      if (flags & THR_DETACHED) my_flags |= DETACHED;
!     if (flags & THR_SUSPENDED) my_flags |= SUSPENDED;
      result = thr_create(stack, stack_size, start_routine,
                        arg, flags & ~THR_DETACHED, &my_new_thread);
--- 928,932 ----
      }
      if (flags & THR_DETACHED) my_flags |= DETACHED;
!     if (flags & THR_SUSPENDED) my_flags |= SUSPNDED;
      result = thr_create(stack, stack_size, start_routine,
                        arg, flags & ~THR_DETACHED, &my_new_thread);

Index: threadlibs.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/threadlibs.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** threadlibs.c        8 Apr 2002 23:36:50 -0000       1.2
--- threadlibs.c        6 Feb 2003 01:35:46 -0000       1.3
***************
*** 20,23 ****
--- 20,29 ----
          printf("-lthread -ldl\n");
  #   endif
+ #   if defined(GC_WIN32_THREADS) && defined(CYGWIN32)
+         printf("-lpthread\n");
+ #   endif
+ #   if defined(GC_OSF1_THREADS)
+       printf("-lpthread -lrt");
+ #   endif
      /* You need GCC 3.0.3 to build this one!           */  
      /* DG/UX native gcc doesnt know what "-pthread" is */

Index: typd_mlc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/typd_mlc.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** typd_mlc.c  9 Nov 2001 02:20:27 -0000       1.1.1.1
--- typd_mlc.c  6 Feb 2003 01:35:46 -0000       1.2
***************
*** 438,441 ****
--- 438,442 ----
        if (bm & 1) {
            current = *current_p;
+           FIXUP_POINTER(current);
            if ((ptr_t)current >= least_ha && (ptr_t)current <= greatest_ha) {
                PUSH_CONTENTS((ptr_t)current, mark_stack_ptr,
***************
*** 675,681 ****
              FASTUNLOCK();
              op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
!           if (0 == op) return(0);
  #         ifdef MERGE_SIZES
!               lw = GC_size_map[lb];   /* May have been uninitialized. */      
      
  #         endif
          } else {
--- 676,682 ----
              FASTUNLOCK();
              op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
!           if (0 == op) return 0;
  #         ifdef MERGE_SIZES
!               lw = GC_size_map[lb];   /* May have been uninitialized. */
  #         endif
          } else {
***************
*** 721,725 ****
              op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
  #         ifdef MERGE_SIZES
!               lw = GC_size_map[lb];   /* May have been uninitialized. */      
      
  #         endif
          } else {
--- 722,726 ----
              op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
  #         ifdef MERGE_SIZES
!               lw = GC_size_map[lb];   /* May have been uninitialized. */
  #         endif
          } else {

Index: version.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/version.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** version.h   8 Apr 2002 23:36:50 -0000       1.2
--- version.h   6 Feb 2003 01:35:46 -0000       1.3
***************
*** 1,5 ****
  #define GC_VERSION_MAJOR 6
! #define GC_VERSION_MINOR 1
! #define GC_ALPHA_VERSION 4
  
  #   define GC_NOT_ALPHA 0xff
--- 1,5 ----
  #define GC_VERSION_MAJOR 6
! #define GC_VERSION_MINOR 2
! #define GC_ALPHA_VERSION 3
  
  #   define GC_NOT_ALPHA 0xff

Index: win32_threads.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/libgc/win32_threads.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** win32_threads.c     16 Dec 2002 03:25:51 -0000      1.3
--- win32_threads.c     6 Feb 2003 01:35:46 -0000       1.4
***************
*** 1,6 ****
! #if defined(GC_WIN32_THREADS)
  
  #include "private/gc_priv.h"
  
  #if 0
  #define STRICT
--- 1,24 ----
! #if defined(GC_WIN32_THREADS) 
  
  #include "private/gc_priv.h"
  
+ #ifdef CYGWIN32
+ # include <errno.h>
+ 
+  /* Cygwin-specific forward decls */
+ # undef pthread_create 
+ # undef pthread_sigmask 
+ # undef pthread_join 
+ # undef dlopen 
+ 
+ # define DEBUG_CYGWIN_THREADS 0
+ 
+   GC_bool GC_thr_initialized = FALSE;
+   void * GC_start_routine(void * arg);
+   void GC_thread_exit_proc(void *arg);
+ 
+ #endif
+ 
+ 
  #if 0
  #define STRICT
***************
*** 8,18 ****
  #endif
  
- /* Temporary hack to work around cygwin 1.3 compile issues */
- #if defined(__CYGWIN__) || defined(__MINGW32__)
- #define       __try
- #define       __except(x)     if(0)
- #define       __finally       if(0)
- #endif
- 
  #define MAX_THREADS 64
  
--- 26,29 ----
***************
*** 26,29 ****
--- 37,46 ----
    CONTEXT context;
    GC_bool suspended;
+ 
+ # ifdef CYGWIN32
+     void *status; /* hold exit value until join in case it's a pointer */
+     pthread_t pthread_id;
+ # endif
+ 
  };
  
***************
*** 37,40 ****
--- 54,63 ----
      /* contains no pointers to the collectable heap.  Thus we have    */
      /* no private structures we need to preserve.                     */
+ # ifdef CYGWIN32
+   { int i; /* pthreads may keep a pointer in the thread exit value */
+     for (i = 0; i < MAX_THREADS; i++)
+       if (thread_table[i].in_use) 
GC_push_all((ptr_t)&(thread_table[i].status),(ptr_t)(&(thread_table[i].status)+1));
+   }
+ #endif
  }
  
***************
*** 44,47 ****
--- 67,74 ----
    int i;
  
+ #ifdef CYGWIN32
+   if (!GC_thr_initialized) ABORT("GC_stop_world() called before 
GC_thr_init()");
+ #endif
+ 
    GC_please_stop = TRUE;
    for (i = 0; i < MAX_THREADS; i++)
***************
*** 61,68 ****
        if (GetExitCodeThread(thread_table[i].handle,&exitCode) &&
              exitCode != STILL_ACTIVE) {
!             thread_table[i].stack = 0;
            thread_table[i].in_use = FALSE;
            CloseHandle(thread_table[i].handle);
            BZERO((void *)(&thread_table[i].context), sizeof(CONTEXT));
            continue;
        }
--- 88,98 ----
        if (GetExitCodeThread(thread_table[i].handle,&exitCode) &&
              exitCode != STILL_ACTIVE) {
!             thread_table[i].stack = 0; /* prevent stack from being pushed */
! #       ifndef CYGWIN32
!           /* this breaks pthread_join on Cygwin, which is guaranteed to only 
see user pthreads */
            thread_table[i].in_use = FALSE;
            CloseHandle(thread_table[i].handle);
            BZERO((void *)(&thread_table[i].context), sizeof(CONTEXT));
+ #endif
            continue;
        }
***************
*** 142,148 ****
          ABORT("GetThreadContext failed");
  #     ifdef I386
-         if (thread_table[i].context.Esp >= (DWORD)thread_table[i].stack
-             || thread_table[i].context.Esp < (DWORD)bottom)
-             ABORT("Thread stack pointer out of range");
          GC_push_one ((word) thread_table[i].context.Edi);
          GC_push_one ((word) thread_table[i].context.Esi);
--- 172,175 ----
***************
*** 152,157 ****
          GC_push_one ((word) thread_table[i].context.Ecx);
          GC_push_one ((word) thread_table[i].context.Eax);
!         GC_push_all_stack((char *) thread_table[i].context.Esp,
!                           thread_table[i].stack);
  #       else
  #       ifdef ARM32
--- 179,191 ----
          GC_push_one ((word) thread_table[i].context.Ecx);
          GC_push_one ((word) thread_table[i].context.Eax);
!         if (thread_table[i].context.Esp >= (DWORD)thread_table[i].stack
!             || thread_table[i].context.Esp < (DWORD)bottom) {
!             WARN("Thread stack pointer 0x%lx out of range, pushing 
everything",
!                  thread_table[i].context.Esp);
!             GC_push_all_stack((char *) bottom, thread_table[i].stack);
!         } else {
!             GC_push_all_stack((char *) thread_table[i].context.Esp,
!                               thread_table[i].stack);
!         }
  #       else
  #       ifdef ARM32
***************
*** 455,461 ****
--- 489,499 ----
      /* This is probably pointless, since an uncaught exception is     */
      /* supposed to result in the process being killed.                        
*/
+ #ifndef __GNUC__
      __try {
+ #endif /* __GNUC__ */
        ret = args.start (args.param);
+ #ifndef __GNUC__
      } __finally {
+ #endif /* __GNUC__ */
        LOCK();
        args.entry->stack = 0;
***************
*** 464,468 ****
--- 502,508 ----
        BZERO((void *) &args.entry->context, sizeof(CONTEXT));
        UNLOCK();
+ #ifndef __GNUC__
      }
+ #endif /* __GNUC__ */
  
      return ret;
***************
*** 525,531 ****
  LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info);
  
  /*
!  * This isn't generally safe, since DllMain is not premptible.
!  * If another thread holds the lock while this runs we're in trouble.
   * Pontus Rydin suggests wrapping the thread start routine instead.
   */
--- 565,813 ----
  LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info);
  
+ /* threadAttach/threadDetach routines used by both CYGWIN and DLL 
implementation,
+    since both recieve explicit notification on thread creation/destruction
+  */
+ void threadAttach() {
+   int i;
+   /* It appears to be unsafe to acquire a lock here, since this       */
+   /* code is apparently not preeemptible on some systems.     */
+   /* (This is based on complaints, not on Microsoft's official        */
+   /* documentation, which says this should perform "only simple       */
+   /* inititalization tasks".)                                 */
+   /* Hence we make do with nonblocking synchronization.               */
+ 
+   /* The following should be a noop according to the win32    */
+   /* documentation.  There is empirical evidence that it      */
+   /* isn't.           - HB                                    */
+ # if defined(MPROTECT_VDB)
+    if (GC_incremental) SetUnhandledExceptionFilter(GC_write_fault_handler);
+ # endif
+                 /* cast away volatile qualifier */
+   for (i = 0; InterlockedExchange((LONG*)&thread_table[i].in_use,1) != 0; 
i++) {
+     /* Compare-and-swap would make this cleaner, but that's not       */
+     /* supported before Windows 98 and NT 4.0.  In Windows 2000,      */
+     /* InterlockedExchange is supposed to be replaced by              */
+     /* InterlockedExchangePointer, but that's not really what I       */
+     /* want here.                                                     */
+     if (i == MAX_THREADS - 1)
+       ABORT("too many threads");
+   }
+   thread_table[i].id = GetCurrentThreadId();
+ # ifdef CYGWIN32
+     thread_table[i].pthread_id = pthread_self();
+ # endif
+   if (!DuplicateHandle(GetCurrentProcess(),
+                      GetCurrentThread(),
+                      GetCurrentProcess(),
+                      (HANDLE*)&thread_table[i].handle,
+                      0,
+                      0,
+                      DUPLICATE_SAME_ACCESS)) {
+       DWORD last_error = GetLastError();
+       GC_printf1("Last error code: %lx\n", last_error);
+       ABORT("DuplicateHandle failed");
+   }
+   thread_table[i].stack = GC_get_stack_base();
+   if (thread_table[i].stack == NULL) 
+     ABORT("Failed to find stack base in threadAttach");
+   /* If this thread is being created while we are trying to stop      */
+   /* the world, wait here.  Hopefully this can't happen on any        */
+   /* systems that don't allow us to block here.                       */
+   while (GC_please_stop) Sleep(20);
+ }
+ 
+ void threadDetach(DWORD thread_id) {
+   int i;
+ 
+   LOCK();
+   for (i = 0;
+        i < MAX_THREADS &&
+        !thread_table[i].in_use || thread_table[i].id != thread_id;
+        i++) {}
+   if (i >= MAX_THREADS ) {
+     WARN("thread %ld not found on detach", (GC_word)thread_id);
+   }
+   else {
+     thread_table[i].stack = 0;
+     thread_table[i].in_use = FALSE;
+     CloseHandle(thread_table[i].handle);
+       /* cast away volatile qualifier */
+     BZERO((void *)&thread_table[i].context, sizeof(CONTEXT));
+   }
+   UNLOCK();
+ }
+ 
+ #ifdef CYGWIN32
+ 
+ /* Called by GC_init() - we hold the allocation lock. */
+ void GC_thr_init() {
+     if (GC_thr_initialized) return;
+     GC_thr_initialized = TRUE;
+ 
+ #if 0
+     /* this might already be handled in GC_init... */
+     InitializeCriticalSection(&GC_allocate_ml);
+ #endif
+ 
+     /* Add the initial thread, so we can stop it.     */
+     threadAttach();
+ }
+ 
+ struct start_info {
+     void *(*start_routine)(void *);
+     void *arg;
+ };
+ 
+ int GC_pthread_join(pthread_t pthread_id, void **retval) {
+     int result;
+     int i;
+ 
+ #   if DEBUG_CYGWIN_THREADS
+       GC_printf3("thread 0x%x(0x%x) is joining thread 
0x%x.\n",(int)pthread_self(),
+                GetCurrentThreadId(), (int)pthread_id);
+ #   endif
+ 
+     /* Can't do any table lookups here, because thread being joined 
+        might not have registered itself yet */
+ 
+     result = pthread_join(pthread_id, retval);
+ 
+     LOCK();
+     for (i = 0; !thread_table[i].in_use || thread_table[i].pthread_id != 
pthread_id;
+          i++) {
+       if (i == MAX_THREADS - 1) {
+         GC_printf1("Failed to find thread 0x%x in pthread_join()\n", 
pthread_id);
+         ABORT("thread not found on detach");
+       }
+     }
+     UNLOCK();
+     threadDetach(thread_table[i].id);
+ 
+ #   if DEBUG_CYGWIN_THREADS
+       GC_printf3("thread 0x%x(0x%x) completed join with thread 0x%x.\n",
+                (int)pthread_self(), GetCurrentThreadId(), (int)pthread_id);
+ #   endif
+ 
+     return result;
+ }
+ 
+ /* Cygwin-pthreads calls CreateThread internally, but it's not
+  * easily interceptible by us..
+  *   so intercept pthread_create instead
+  */
+ int
+ GC_pthread_create(pthread_t *new_thread,
+                 const pthread_attr_t *attr,
+                   void *(*start_routine)(void *), void *arg) {
+     int result;
+     struct start_info * si;
+ 
+     if (!GC_is_initialized) GC_init();
+               /* make sure GC is initialized (i.e. main thread is attached) */
+     
+     /* This is otherwise saved only in an area mmapped by the thread */
+     /* library, which isn't visible to the collector.          */
+     si = GC_malloc_uncollectable(sizeof(struct start_info)); 
+     if (0 == si) return(EAGAIN);
+ 
+     si -> start_routine = start_routine;
+     si -> arg = arg;
+ 
+ #   if DEBUG_CYGWIN_THREADS
+       GC_printf2("About to create a thread from 
0x%x(0x%x)\n",(int)pthread_self(),
+                                                             
GetCurrentThreadId);
+ #   endif
+     result = pthread_create(new_thread, attr, GC_start_routine, si); 
+ 
+     if (result) { /* failure */
+               GC_free(si);
+     } 
+ 
+     return(result);
+ }
+ 
+ void * GC_start_routine(void * arg)
+ {
+     struct start_info * si = arg;
+     void * result;
+     void *(*start)(void *);
+     void *start_arg;
+     pthread_t pthread_id;
+     int i;
+ 
+ #   if DEBUG_CYGWIN_THREADS
+       GC_printf2("thread 0x%x(0x%x) starting...\n",(int)pthread_self(),
+                                                  GetCurrentThreadId());
+ #   endif
+ 
+     /* If a GC occurs before the thread is registered, that GC will   */
+     /* ignore this thread.  That's fine, since it will block trying to  */
+     /* acquire the allocation lock, and won't yet hold interesting    */
+     /* pointers.                                                      */
+     LOCK();
+     /* We register the thread here instead of in the parent, so that  */
+     /* we don't need to hold the allocation lock during pthread_create. */
+     threadAttach();
+     UNLOCK();
+ 
+     start = si -> start_routine;
+     start_arg = si -> arg;
+     pthread_id = pthread_self();
+ 
+     GC_free(si); /* was allocated uncollectable */
+ 
+     pthread_cleanup_push(GC_thread_exit_proc, pthread_id);
+     result = (*start)(start_arg);
+     pthread_cleanup_pop(0);
+ 
+ #   if DEBUG_CYGWIN_THREADS
+       GC_printf2("thread 0x%x(0x%x) returned from start routine.\n",
+                (int)pthread_self(),GetCurrentThreadId());
+ #   endif
+ 
+     LOCK();
+     for (i = 0; thread_table[i].pthread_id != pthread_id; i++) {
+       if (i == MAX_THREADS - 1)
+         ABORT("thread not found on exit");
+     }
+     thread_table[i].status = result;
+     UNLOCK();
+ 
+     return(result);
+ }
+ 
+ void GC_thread_exit_proc(void *arg)
+ {
+     pthread_t pthread_id = (pthread_t)arg;
+     int i;
+ 
+ #   if DEBUG_CYGWIN_THREADS
+       GC_printf2("thread 0x%x(0x%x) called 
pthread_exit().\n",(int)pthread_self(),GetCurrentThreadId());
+ #   endif
+ 
+     LOCK();
+     for (i = 0; thread_table[i].pthread_id != pthread_id; i++) {
+       if (i == MAX_THREADS - 1)
+         ABORT("thread not found on exit");
+     }
+     UNLOCK();
+ 
+ #if 0
+     /* TODO: we need a way to get the exit value after a pthread_exit so we 
can stash it safely away */
+     thread_table[i].status = ???
+ #endif
+ }
+ 
+ /* nothing required here... */
+ int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) {
+   return pthread_sigmask(how, set, oset);
+ }
+ int GC_pthread_detach(pthread_t thread) {
+   return pthread_detach(thread);
+ }
+ #else
+ 
  /*
!  * We avoid acquiring locks here, since this doesn't seem to be preemptable.
   * Pontus Rydin suggests wrapping the thread start routine instead.
   */
***************
*** 538,610 ****
      /* fall through */
    case DLL_THREAD_ATTACH:
!     {
!       int i;
!       /* It appears to be unsafe to acquire a lock here, since this   */
!       /* code is apparently not preeemptible on some systems.         */
!       /* (This is based on complaints, not on Microsoft's official    */
!       /* documentation, which says this should perform "only simple   */
!       /* inititalization tasks".)                                     */
!       /* Hence we make do with nonblocking synchronization.           */
! 
!       /* The following should be a noop according to the win32        */
!       /* documentation.  There is empirical evidence that it  */
!       /* isn't.               - HB                                    */
! #     ifdef MPROTECT_VDB
!        if (GC_incremental) 
SetUnhandledExceptionFilter(GC_write_fault_handler);
! #     endif
! 
!       for (i = 0;
!                              /* cast away volatile qualifier */
!          InterlockedExchange((LPLONG) &thread_table[i].in_use, 1) != 0;
!          i++) {
!       /* Compare-and-swap would make this cleaner, but that's not     */
!       /* supported before Windows 98 and NT 4.0.  In Windows 2000,    */
!       /* InterlockedExchange is supposed to be replaced by            */
!       /* InterlockedExchangePointer, but that's not really what I     */
!       /* want here.                                                   */
!       if (i == MAX_THREADS - 1)
!         ABORT("too many threads");
!       }
!       thread_table[i].id = GetCurrentThreadId();
!       if (!DuplicateHandle(GetCurrentProcess(),
!                          GetCurrentThread(),
!                          GetCurrentProcess(),
!                          /* cast away volatile qualifier */
!                          (HANDLE *) &thread_table[i].handle,
!                          0,
!                          0,
!                          DUPLICATE_SAME_ACCESS)) {
!       DWORD last_error = GetLastError();
!       GC_printf1("Last error code: %lx\n", last_error);
!       ABORT("DuplicateHandle failed");
!       }
!       thread_table[i].stack = GC_get_stack_base();
!       /* If this thread is being created while we are trying to stop  */
!       /* the world, wait here.  Hopefully this can't happen on any    */
!       /* systems that don't allow us to block here.                   */
!       while (GC_please_stop) Sleep(20);
!     }
      break;
    case DLL_THREAD_DETACH:
!     {
!       int i;
!       DWORD thread_id = GetCurrentThreadId();
!       LOCK();
!       for (i = 0;
!            i < MAX_THREADS &&
!          (thread_table[i].stack == 0 || thread_table[i].id != thread_id);
!          i++) {}
!       if (i >= MAX_THREADS) {
!         WARN("thread %ld not found on detach", (GC_word)thread_id);
!       } else {
!           thread_table[i].stack = 0;
!           thread_table[i].in_use = FALSE;
!           CloseHandle(thread_table[i].handle);
!           /* cast away volatile qualifier */
!           BZERO((void *) &thread_table[i].context, sizeof(CONTEXT));
!       }
!       UNLOCK();
!     }
      break;
    case DLL_PROCESS_DETACH:
      {
--- 820,830 ----
      /* fall through */
    case DLL_THREAD_ATTACH:
!     threadAttach();
      break;
+ 
    case DLL_THREAD_DETACH:
!     threadDetach(GetCurrentThreadId());
      break;
+ 
    case DLL_PROCESS_DETACH:
      {
***************
*** 632,635 ****
--- 852,856 ----
    return TRUE;
  }
+ #endif /* CYGWIN32 */
  
  # endif /* !MSWINCE */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]