]> granicus.if.org Git - gc/commitdiff
gc6.3 tarball import gc6_3
authorIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 13:51:40 +0000 (17:51 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 13:51:40 +0000 (17:51 +0400)
35 files changed:
Makefile
Makefile.am
Makefile.direct
Makefile.in
NT_STATIC_THREADS_MAKEFILE
allchblk.c
alloc.c
checksums.c
configure
configure.in
darwin_stop_world.c
dbg_mlc.c
doc/Makefile.am
doc/Makefile.in
doc/README
doc/README.changes
doc/simple_example.html [new file with mode: 0644]
dyn_load.c
headers.c
include/gc.h
include/gc_allocator.h
include/gc_config_macros.h
include/private/gc_priv.h
include/private/gcconfig.h
ltconfig [deleted file]
mark.c
new_hblk.c
os_dep.c
pthread_stop_world.c
solaris_pthreads.c
solaris_threads.c
tests/middle.c [new file with mode: 0644]
tests/test.c
threadlibs.c
version.h

index 74929c18ba6de9b33f5b05e0eb32c0e21b6c20d5..20fa40a9a08ce365de46adbf440afbec2560bee6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -320,14 +320,15 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
        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 \
-       doc/scale.html doc/gcinterface.html doc/README.darwin
+       doc/scale.html doc/gcinterface.html doc/README.darwin \
+       doc/simple_example.html
 
 TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
-       tests/leak_test.c tests/thread_leak_test.c
+       tests/leak_test.c tests/thread_leak_test.c tests/middle.c
 
 GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \
                 libtool.m4 install-sh configure.host Makefile.in \
-                ltconfig aclocal.m4 config.sub config.guess \
+                aclocal.m4 config.sub config.guess \
                 include/Makefile.am include/Makefile.in \
                 doc/Makefile.am doc/Makefile.in \
                 ltmain.sh mkinstalldirs depcomp missing
@@ -367,16 +368,23 @@ SPECIALCFLAGS = -I$(srcdir)/include
 
 all: gc.a gctest
 
-BSD-pkg-all: bsd-libgc.a
+LEAKFLAGS=$(CFLAGS) -DFIND_LEAK
+
+BSD-pkg-all: bsd-libgc.a bsd-libleak.a
 
 bsd-libgc.a:
        $(MAKE) CFLAGS="$(CFLAGS)" clean c++-t
        mv gc.a bsd-libgc.a
 
+bsd-libleak.a:
+       $(MAKE) -f Makefile.direct CFLAGS="$(LEAKFLAGS)" clean c++-nt
+       mv gc.a bsd-libleak.a
+
 BSD-pkg-install: BSD-pkg-all
        ${CP} bsd-libgc.a libgc.a
        ${INSTALL_DATA} libgc.a ${PREFIX}/lib
        ${INSTALL_DATA} gc.h gc_cpp.h ${PREFIX}/include
+       ${INSTALL_MAN} doc/gc.man ${PREFIX}/man/man3/gc.3
 
 pcr: PCR-Makefile include/private/gc_private.h include/private/gc_hdrs.h \
 include/private/gc_locks.h include/gc.h include/private/gcconfig.h \
index ed24152fe5dcab03ee125d75b4dc102fd85968e9..2aba243231f66c026a34ff2492669cfb3b20f81e 100644 (file)
@@ -85,7 +85,7 @@ 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
+       $(CXXCOMPILE) -c $(srcdir)/tests/test_cpp.cc
 
 ## FIXME: this is probably the reason why some files from BUILT_SOURCES
 ##     are included in the distribution
index 74929c18ba6de9b33f5b05e0eb32c0e21b6c20d5..20fa40a9a08ce365de46adbf440afbec2560bee6 100644 (file)
@@ -320,14 +320,15 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
        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 \
-       doc/scale.html doc/gcinterface.html doc/README.darwin
+       doc/scale.html doc/gcinterface.html doc/README.darwin \
+       doc/simple_example.html
 
 TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
-       tests/leak_test.c tests/thread_leak_test.c
+       tests/leak_test.c tests/thread_leak_test.c tests/middle.c
 
 GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \
                 libtool.m4 install-sh configure.host Makefile.in \
-                ltconfig aclocal.m4 config.sub config.guess \
+                aclocal.m4 config.sub config.guess \
                 include/Makefile.am include/Makefile.in \
                 doc/Makefile.am doc/Makefile.in \
                 ltmain.sh mkinstalldirs depcomp missing
@@ -367,16 +368,23 @@ SPECIALCFLAGS = -I$(srcdir)/include
 
 all: gc.a gctest
 
-BSD-pkg-all: bsd-libgc.a
+LEAKFLAGS=$(CFLAGS) -DFIND_LEAK
+
+BSD-pkg-all: bsd-libgc.a bsd-libleak.a
 
 bsd-libgc.a:
        $(MAKE) CFLAGS="$(CFLAGS)" clean c++-t
        mv gc.a bsd-libgc.a
 
+bsd-libleak.a:
+       $(MAKE) -f Makefile.direct CFLAGS="$(LEAKFLAGS)" clean c++-nt
+       mv gc.a bsd-libleak.a
+
 BSD-pkg-install: BSD-pkg-all
        ${CP} bsd-libgc.a libgc.a
        ${INSTALL_DATA} libgc.a ${PREFIX}/lib
        ${INSTALL_DATA} gc.h gc_cpp.h ${PREFIX}/include
+       ${INSTALL_MAN} doc/gc.man ${PREFIX}/man/man3/gc.3
 
 pcr: PCR-Makefile include/private/gc_private.h include/private/gc_hdrs.h \
 include/private/gc_locks.h include/gc.h include/private/gcconfig.h \
index 2c7c1b72b9f1b4276f99ff2a7631bda6127ff4c0..fb52a370675268baf3100280e23e7834d10793ff 100644 (file)
@@ -326,7 +326,7 @@ RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
 DIST_COMMON = $(dist_noinst_HEADERS) $(dist_noinst_SCRIPTS) \
        $(include_HEADERS) Makefile.am Makefile.in acinclude.m4 \
        aclocal.m4 config.guess config.sub configure configure.in \
-       depcomp install-sh ltconfig ltmain.sh missing mkinstalldirs
+       depcomp install-sh ltmain.sh missing mkinstalldirs
 DIST_SUBDIRS = $(SUBDIRS)
 SOURCES = $(libgc_la_SOURCES) $(EXTRA_libgc_la_SOURCES) $(libgccpp_la_SOURCES) $(gctest_SOURCES) $(test_cpp_SOURCES)
 
@@ -902,7 +902,7 @@ 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
+       $(CXXCOMPILE) -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_pthread_redirects.h include/gc_config_macros.h \
index 7238c9400cfdf69704b87519db19de141f557613..a7582af620b821f7d7fca00e9c875a2a7e1c7a9b 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile for Windows NT.  Assumes Microsoft compiler, and a single thread.
+# Makefile for Windows NT.  Assumes Microsoft compiler.
 # DLLs are included in the root set under NT, but not under win32S.
 # Use "nmake nodebug=1 all" for optimized versions of library, gctest and editor.
 
index 1bd17da3b7a8012ed5d437a01df8e222a9b02f90..793c468b928c4b8364c86d9937c01d2c28943650 100644 (file)
@@ -111,7 +111,7 @@ void GC_print_hblkfreelist()
     for (i = 0; i <= N_HBLK_FLS; ++i) {
       h = GC_hblkfreelist[i];
 #     ifdef USE_MUNMAP
-        if (0 != h) GC_printf1("Free list %ld (Total size %ld):\n",
+        if (0 != h) GC_printf1("Free list %ld:\n",
                               (unsigned long)i);
 #     else
         if (0 != h) GC_printf2("Free list %ld (Total size %ld):\n",
@@ -133,10 +133,12 @@ void GC_print_hblkfreelist()
         h = hhdr -> hb_next;
       }
     }
-    if (total_free != GC_large_free_bytes) {
+#   ifndef USE_MUNMAP
+      if (total_free != GC_large_free_bytes) {
        GC_printf1("GC_large_free_bytes = %lu (INCONSISTENT!!)\n",
                   (unsigned long) GC_large_free_bytes);
-    }
+      }
+#   endif
     GC_printf1("Total of %lu bytes on free list\n", (unsigned long)total_free);
 }
 
@@ -181,7 +183,7 @@ void GC_dump_regions()
            hhdr = HDR(p);
            GC_printf1("\t0x%lx ", (unsigned long)p);
            if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
-               GC_printf1("Missing header!!\n", hhdr);
+               GC_printf1("Missing header!!(%ld)\n", hhdr);
                p += HBLKSIZE;
                continue;
            }
@@ -468,7 +470,11 @@ int index;
     if (total_size == bytes) return h;
     rest = (struct hblk *)((word)h + bytes);
     rest_hdr = GC_install_header(rest);
-    if (0 == rest_hdr) return(0);
+    if (0 == rest_hdr) {
+       /* This may be very bad news ... */
+       WARN("Header allocation failed: Dropping block.\n", 0);
+       return(0);
+    }
     rest_hdr -> hb_sz = total_size - bytes;
     rest_hdr -> hb_flags = 0;
 #   ifdef GC_ASSERTIONS
diff --git a/alloc.c b/alloc.c
index aaf9124cd52444be76d4f14b8f95c8abbe29e64c..1ac6ff8111f923f208683bacb9895b13f1313565 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -133,7 +133,7 @@ int GC_n_attempts = 0;              /* Number of attempts at finishing      */
          if (GC_print_stats) {
            GC_printf0("Abandoning stopped marking after ");
            GC_printf1("%lu msecs", (unsigned long)time_diff);
-           GC_printf1("(attempt %d)\n", (unsigned long) GC_n_attempts);
+           GC_printf1("(attempt %ld)\n", (unsigned long) GC_n_attempts);
          }
 #      endif
        return(1);
@@ -942,12 +942,7 @@ word n;
             (GC_PTR)GC_min((ptr_t)GC_least_plausible_heap_addr,
                            (ptr_t)space - expansion_slop);
     }
-    /* Force GC before we are likely to allocate past expansion_slop */
-      GC_collect_at_heapsize =
-         GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE;
 #   if defined(LARGE_CONFIG)
-      if (GC_collect_at_heapsize < GC_heapsize /* wrapped */)
-       GC_collect_at_heapsize = (word)(-1);
       if (((ptr_t)GC_greatest_plausible_heap_addr <= (ptr_t)space + bytes
            || (ptr_t)GC_least_plausible_heap_addr >= (ptr_t)space)
          && GC_heapsize > 0) {
@@ -958,6 +953,13 @@ word n;
     GC_prev_heap_addr = GC_last_heap_addr;
     GC_last_heap_addr = (ptr_t)space;
     GC_add_to_heap(space, bytes);
+    /* Force GC before we are likely to allocate past expansion_slop */
+      GC_collect_at_heapsize =
+         GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE;
+#     if defined(LARGE_CONFIG)
+        if (GC_collect_at_heapsize < GC_heapsize /* wrapped */)
+         GC_collect_at_heapsize = (word)(-1);
+#     endif
     return(TRUE);
 }
 
index 121c36d4be2f338cb5fd183ee40dd4e07380238d..57a6ebc2160f5ad4a9c726c8a9ccf0eb17cc9af0 100644 (file)
 /* Boehm, March 29, 1995 12:51 pm PST */
 # ifdef CHECKSUMS
 
-# include "gc_priv.h"
+# include "private/gc_priv.h"
 
 /* This is debugging code intended to verify the results of dirty bit  */
 /* computations. Works only in a single threaded environment.          */
 /* We assume that stubborn objects are changed only when they are      */
 /* enabled for writing.  (Certain kinds of writing are actually                */
 /* safe under other conditions.)                                       */
-# define NSUMS 2000
+# define NSUMS 10000
 
 # define OFFSET 0x10000
 
@@ -29,7 +29,7 @@ typedef struct {
        word old_sum;
        word new_sum;
        struct hblk * block;    /* Block to which this refers + OFFSET  */
-                               /* to hide it from colector.            */
+                               /* to hide it from collector.           */
 } page_entry;
 
 page_entry GC_sums [NSUMS];
@@ -76,12 +76,13 @@ int index;
 {
     page_entry *pe = GC_sums + index;
     register hdr * hhdr = HDR(h);
+    struct hblk *b;
     
     if (pe -> block != 0 && pe -> block != h + OFFSET) ABORT("goofed");
     pe -> old_sum = pe -> new_sum;
     pe -> new_sum = GC_checksum(h);
 #   if !defined(MSWIN32) && !defined(MSWINCE)
-        if (pe -> new_sum != 0 && !GC_page_was_ever_dirty(h)) {
+        if (pe -> new_sum != 0x80000000 && !GC_page_was_ever_dirty(h)) {
             GC_printf1("GC_page_was_ever_dirty(0x%lx) is wrong\n",
                       (unsigned long)h);
         }
@@ -91,13 +92,19 @@ int index;
     } else {
        GC_n_clean++;
     }
-    if (pe -> new_valid && pe -> old_sum != pe -> new_sum) {
+    b = h;
+    while (IS_FORWARDING_ADDR_OR_NIL(hhdr) && hhdr != 0) {
+       b -= (word)hhdr;
+       hhdr = HDR(b);
+    }
+    if (pe -> new_valid
+       && hhdr != 0 && hhdr -> hb_descr != 0 /* may contain pointers */
+       && pe -> old_sum != pe -> new_sum) {
        if (!GC_page_was_dirty(h) || !GC_page_was_ever_dirty(h)) {
            /* Set breakpoint here */GC_n_dirty_errors++;
        }
 #      ifdef STUBBORN_ALLOC
-         if (!IS_FORWARDING_ADDR_OR_NIL(hhdr)
-           && hhdr -> hb_map != GC_invalid_map
+         if ( hhdr -> hb_map != GC_invalid_map
            && hhdr -> hb_obj_kind == STUBBORN
            && !GC_page_was_changed(h)
            && !GC_on_free_list(h)) {
@@ -120,26 +127,17 @@ word dummy;
    register hdr * hhdr = HDR(h);
    register bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
    
-   bytes += HDR_BYTES + HBLKSIZE-1;
+   bytes += HBLKSIZE-1;
    bytes &= ~(HBLKSIZE-1);
    GC_bytes_in_used_blocks += bytes;
 }
 
 void GC_check_blocks()
 {
-    word bytes_in_free_blocks = 0;
-    struct hblk * h = GC_hblkfreelist;
-    hdr * hhdr = HDR(h);
-    word sz;
+    word bytes_in_free_blocks = GC_large_free_bytes;
     
     GC_bytes_in_used_blocks = 0;
     GC_apply_to_all_blocks(GC_add_block, (word)0);
-    while (h != 0) {
-        sz = hhdr -> hb_sz;
-        bytes_in_free_blocks += sz;
-        h = hhdr -> hb_next;
-        hhdr = HDR(h);
-    }
     GC_printf2("GC_bytes_in_used_blocks = %ld, bytes_in_free_blocks = %ld ",
                GC_bytes_in_used_blocks, bytes_in_free_blocks);
     GC_printf1("GC_heapsize = %ld\n", GC_heapsize);
index 3ede246cd68e66b41d0f7a70c26ceaa70658ddd2..7c4d08b9591338ffbf82f85d2b30d293a5323e4b 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision: 1.2 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.53 for gc 6.3alpha5.
+# Generated by GNU Autoconf 2.53 for gc 6.3.
 #
 # Report bugs to <Hans.Boehm@hp.com>.
 #
@@ -416,8 +416,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='gc'
 PACKAGE_TARNAME='gc'
-PACKAGE_VERSION='6.3alpha5'
-PACKAGE_STRING='gc 6.3alpha5'
+PACKAGE_VERSION='6.3'
+PACKAGE_STRING='gc 6.3'
 PACKAGE_BUGREPORT='Hans.Boehm@hp.com'
 
 ac_unique_file="gcj_mlc.c"
@@ -930,7 +930,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures gc 6.3alpha5 to adapt to many kinds of systems.
+\`configure' configures gc 6.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -997,7 +997,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of gc 6.3alpha5:";;
+     short | recursive ) echo "Configuration of gc 6.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1106,7 +1106,7 @@ fi
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-gc configure 6.3alpha5
+gc configure 6.3
 generated by GNU Autoconf 2.53
 
 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
@@ -1121,7 +1121,7 @@ cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by gc $as_me 6.3alpha5, which was
+It was created by gc $as_me 6.3, which was
 generated by GNU Autoconf 2.53.  Invocation command line was
 
   $ $0 $@
@@ -1782,7 +1782,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=gc
- VERSION=6.3alpha5
+ VERSION=6.3
 
 
 cat >>confdefs.h <<_ACEOF
@@ -8558,8 +8558,6 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 #
 # Check for AViiON Machines running DGUX
 #
-echo "$as_me:$LINENO: checking if host is AViiON running DGUX" >&5
-echo $ECHO_N "checking if host is AViiON running DGUX... $ECHO_C" >&6
 ac_is_dgux=no
 if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then
   echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5
@@ -8668,8 +8666,6 @@ fi
 
 
 
-echo "$as_me:$LINENO: result: $ac_is_dgux" >&5
-echo "${ECHO_T}$ac_is_dgux" >&6
     ## :GOTCHA: we do not check anything but sys/dg_sys_info.h
 if test $ac_is_dgux = yes; then
     if test "$enable_full_debug" = "yes"; then
@@ -9347,7 +9343,7 @@ _ASBOX
 } >&5
 cat >&5 <<_CSEOF
 
-This file was extended by gc $as_me 6.3alpha5, which was
+This file was extended by gc $as_me 6.3, which was
 generated by GNU Autoconf 2.53.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9404,7 +9400,7 @@ _ACEOF
 
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-gc config.status 6.3alpha5
+gc config.status 6.3
 configured by $0, generated by GNU Autoconf 2.53,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
index 635742cfc12acac47e4a154f32e12ec152a90428..7914692d21a4080d1247d78202b1345999fcbb27 100644 (file)
@@ -17,7 +17,7 @@ dnl Process this file with autoconf to produce configure.
 # Initialization
 # ==============
 
-AC_INIT(gc,6.3alpha5,Hans.Boehm@hp.com) 
+AC_INIT(gc,6.3,Hans.Boehm@hp.com) 
     ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
 AC_CONFIG_SRCDIR(gcj_mlc.c)
 AC_CANONICAL_TARGET 
@@ -308,12 +308,10 @@ AC_PROG_LIBTOOL
 #
 # Check for AViiON Machines running DGUX
 #
-AC_MSG_CHECKING(if host is AViiON running DGUX)
 ac_is_dgux=no
 AC_CHECK_HEADER(sys/dg_sys_info.h,
 [ac_is_dgux=yes;])
 
-AC_MSG_RESULT($ac_is_dgux) 
     ## :GOTCHA: we do not check anything but sys/dg_sys_info.h
 if test $ac_is_dgux = yes; then
     if test "$enable_full_debug" = "yes"; then
index 02d751ed66ff4987b2b99ec6802f5bd4ac04e908..36378cbbce01102c9bd6aca5f56009635a705d2b 100644 (file)
@@ -210,22 +210,39 @@ int GC_suspend_thread_list(thread_act_array_t act_list, int count,
       mach_msg_type_number_t outCount = THREAD_INFO_MAX;
       kern_return_t kern_result = thread_info(thread, THREAD_BASIC_INFO,
                                (thread_info_t)&info, &outCount);
-      if(kern_result != KERN_SUCCESS) ABORT("thread_info failed");
+      if(kern_result != KERN_SUCCESS) {
+       /* the thread may have quit since the thread_threads () call 
+        * we mark already_suspended so it's not dealt with anymore later
+        */
+        if (!found) {
+         GC_mach_threads[GC_mach_threads_count].already_suspended = TRUE;
+         GC_mach_threads_count++;
+       }
+       continue;
+      }
 #     if DEBUG_THREADS
         GC_printf2("Thread state for 0x%lx = %d\n", thread, info.run_state);
 #     endif
       if (!found) {
-       GC_mach_threads[GC_mach_threads_count].already_suspended =
-         (info.run_state != TH_STATE_RUNNING);
+       GC_mach_threads[GC_mach_threads_count].already_suspended = info.suspend_count;
       }
-      if (info.run_state != TH_STATE_RUNNING) continue;
+      if (info.suspend_count) continue;
       
 #     if DEBUG_THREADS
         GC_printf1("Suspending 0x%lx\n", thread);
 #     endif
       /* Suspend the thread */
       kern_result = thread_suspend(thread);
-      if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed");
+      if(kern_result != KERN_SUCCESS) {
+       /* the thread may have quit since the thread_threads () call 
+        * we mark already_suspended so it's not dealt with anymore later
+        */
+        if (!found) {
+         GC_mach_threads[GC_mach_threads_count].already_suspended = TRUE;
+         GC_mach_threads_count++;
+       }
+       continue;
+      }
     } 
     if (!found) GC_mach_threads_count++;
   }
index 9daa0b0db9aa749e0cf031db6dde8c744f478242..aacbb7a1b632e091c6a7cd97f89b587aa2bd83a6 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -818,7 +818,15 @@ GC_PTR p;
                    uncollectable = TRUE;
            }
 #      endif
-       if (uncollectable) GC_free(base);
+       if (uncollectable) {
+           GC_free(base);
+       } else {
+           size_t i;
+           size_t obj_sz = hhdr -> hb_sz - BYTES_TO_WORDS(sizeof(oh));
+
+           for (i = 0; i < obj_sz; ++i) ((word *)p)[i] = 0xdeadbeef;
+           GC_ASSERT((word *)p + i == (word *)base + hhdr -> hb_sz);
+       }
     } /* !GC_find_leak */
 }
 
index 91446305581d47665e67c3ae90f4e0cac0c517ea..9446bcb1ad357ee77480a5c25614be6a17ff07e0 100644 (file)
@@ -23,5 +23,5 @@ dist_pkgdata_DATA = barrett_diagram debugging.html gc.man \
     README.MacOSX README.macros README.OS2 README.rs6000 \
     README.sgi README.solaris2 README.uts README.win32 \
     tree.html leak.html gcinterface.html scale.html \
-    README.darwin
+    README.darwin simple_example.html
 
index 1e9dd9298f4b0c977e161a54ff37c567e1a5015b..708fd51bc3fa9ed01adafc734942064e77c7ef12 100644 (file)
@@ -127,7 +127,7 @@ dist_pkgdata_DATA = barrett_diagram debugging.html gc.man \
     README.MacOSX README.macros README.OS2 README.rs6000 \
     README.sgi README.solaris2 README.uts README.win32 \
     tree.html leak.html gcinterface.html scale.html \
-    README.darwin
+    README.darwin simple_example.html
 
 subdir = doc
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
index 0776e678a3dcb19c6ea48d73cecdfd4f7db8af98..ff77113ee8ca21df7e3add510a3e8b0f1dea6dd4 100644 (file)
@@ -28,7 +28,7 @@ are GPL'ed, but with an exception that should cover all uses in the
 collector.  (If you are concerned about such things, I recommend you look
 at the notice in config.guess or ltmain.sh.)
 
-This is version 6.3alpha5 of a conservative garbage collector for C and C++.
+This is version 6.3 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
index 38bde346965357222e10d279fc8a1d8011187c45..e27e7d635b650d5a265bc9972f96be2cbfa53a30 100644 (file)
@@ -2049,9 +2049,57 @@ Since 6.3alpha4:
  - The USE_MUNMAP code could get confused about the age of a block and
    prematurely unmap it.  GC_unmap_old had a bug related to wrapping of
    GC_gc_no.  GC_freehblk and GC_merge_unmapped didn't maintain
-   hb_last_reclaimed reasonably when blockas were merged.  The code was
+   hb_last_reclaimed reasonably when blocks were merged.  The code was
    fixed to reflect original intent, but that may not always be an
    improvement.  See todo list item.
+
+Since 6.3alpha5:
+ - Define USE_GENERIC_PUSH_REGS for NetBSD/M68K.
+ - Fixed the X86_64 PREFETCH macros to correctly handle ia32e (which uses
+   different prefetch instructions from AMD64).  (Thanks to H.J. Lu.)
+ - GC_config_macros.h did not correctly define GC_WIN32_THREADS from
+   GC_THREADS. 
+ - Added simple_example.html.
+ - Merged Andrew Gray's patch to correctly restore signal handlers on
+   FreeBSD.
+ - Merged a patch from Andreas Jaeger to deal with prefetch-related warnings
+   on x86-64.  Added some other casts so that the PREFETCH macros
+   always get a ptr_t argument.  Removed some casts inthe PREFETCH
+   implementations.
+ - At Jesse Jones suggestion: Added a header guard for gc_allocator.h
+   and changed GC_debug_free to clobber contents of deallocated object.
+ - The signal masking code in pthread_stop_world.c contained some errors.
+   In particular SIGSEGV was masked in the handler, in spite of the fact that
+   it wrote to the heap.  This could lead to an uncaught SIGSEGV, which
+   apparently became much more likely in Linux 2.6.  Also fixed some
+   typos, and reduced code duplication in the same area.
+ - Remove ltconfig, clean up configure messages for DGUX (thanks to
+   Adrian Bunk for the patches).
+ - Integrated NetBSD/OpenBSD patches from Marc Recht and Matthias Drochner.
+
+Since gc6.3alpha6:
+ - Compile test_cpp.cc with CXXCOMPILE instead of COMPILE.
+ - Very large allocations could cause a collector hang.  Correct
+   calculation of GC_collect_at_heapsize.
+ - GC_print_hblkfreelist printed some bogus results if USE_MUNMAP
+   was defined.
+ - The generic GC_THREADS macro didn't work correctly on Solaris,
+   since the implementation failed to include gc_config_macros.h
+   before deciding whether or not to compile the rest of the file.
+ - Threadlibs.c failed to expand the generic GC_THREADS macro.
+ - Correct MacOSX thread stop code. (Thanks to Dick Porter.)
+ - SMALL_OBJ definition was off by one.  This could cause crashes
+   at startup.  (Thanks to Zoltan Varga for narrowing this down to
+   a trivial test case.)
+ - Integrate Paolo Molara's patch to deal with a race in the Darwin
+   thread stopping code.
+ - Changed X86_64 implementation to use SA_SIGINFO in the MPROTECT_VDB
+   implementation.  The old approach appears to have been broken by
+   recent kernels.
+ - Add GC_ATTR_UNUSED to eliminate a warning in gc_allocator.h.  (Thanks
+   to Andrew Begel.)
+ - Fix GC_task_self declaration in os_dep.c.  (Thanks to Andrew Pinski.)
+ - Increase INITIAL_BUF_SZ in os_dep.c for Solaris /proc reads.
   
 To do:
  - The USE_MUNMAP code should really use a separate data structure
diff --git a/doc/simple_example.html b/doc/simple_example.html
new file mode 100644 (file)
index 0000000..0bc0953
--- /dev/null
@@ -0,0 +1,202 @@
+<HTML>
+<HEAD>
+<TITLE>Using the Garbage Collector: A simple example</title>
+</head>
+<BODY>
+<H1>Using the Garbage Collector: A simple example</h1>
+The following consists of step-by-step instructions for building and
+using the collector.  We'll assume a Linux/gcc platform and
+a single-threaded application.  <FONT COLOR=green>The green
+text contains information about other platforms or scenarios.
+It can be skipped, especially on first reading</font>.
+<H2>Building the collector</h2>
+If you haven't already so, unpack the collector and enter
+the newly created directory with
+<PRE>
+tar xvfz gc<version>.tar.gz
+cd gc<version>
+</pre>
+<P>
+You can configure, build, and install the collector in a private
+directory, say /home/xyz/gc, with the following commands:
+<PRE>
+./configure --prefix=/home/xyz/gc --disable-threads
+make
+make check
+make install
+</pre>
+Here the "<TT>make check</tt>" command is optional, but highly recommended.
+It runs a basic correctness test which usually takes well under a minute.
+<FONT COLOR=green>
+<H3>Other platforms</h3>
+On non-Unix, non-Linux platforms, the collector is usually built by copying
+the appropriate makefile (see the platform-specific README in doc/README.xxx
+in the distribution) to the file "Makefile" (overwriting the copy of
+Makefile.direct that was originally there), and then typing "make"
+(or "nmake" or ...).  This builds the library in the source tree.  You may
+want to move it and the files in the include directory to a more convenient
+place.
+<P>
+If you use a makefile that does not require running a configure script,
+you should first look at the makefile, and adjust any options that are
+documented there.
+<P>
+If your platform provides a "make" utility, that is generally preferred
+to platform- and compiler- dependent "project" files.  (At least that is the
+strong preference of the would-be maintainer of those project files.)
+<H3>Threads</h3>
+If you need thread support, configure the collector with
+<PRE>
+--enable-threads=posix --enable-thread-local-alloc --enable-parallel-mark
+</pre>
+instead of
+<TT>--disable-threads</tt>
+If your target is a real old-fashioned uniprocessor (no "hyperthreading",
+etc.) you will want to omit <TT>--enable-parallel-mark</tt>.
+<H3>C++</h3>
+You will need to include the C++ support, which unfortunately tends to
+be among the least portable parts of the collector, since it seems
+to rely on some corner cases of the language.  On Linux, it
+suffices to add <TT>--enable-cplusplus</tt> to the configure options.
+</font>
+<H2>Writing the program</h2>
+You will need a
+<PRE>
+#include "gc.h"
+</pre>
+at the beginning of every file that allocates memory through the
+garbage collector.  Call <TT>GC_MALLOC</tt> wherever you would
+have call <TT>malloc</tt>.  This initializes memory to zero like
+<TT>calloc</tt>; there is no need to explicitly clear the
+result.
+<P>
+If you know that an object will not contain pointers to the
+garbage-collected heap, and you don't need it to be initialized,
+call <TT>GC_MALLOC_ATOMIC</tt> instead.
+<P>
+A function <TT>GC_FREE</tt> is provided but need not be called.
+For very small objects, your program will probably perform better if
+you do not call it, and let the collector do its job.
+<P>
+A <TT>GC_REALLOC</tt> function behaves like the C library <TT>realloc</tt>.
+It allocates uninitialized pointer-free memory if the original
+object was allocated that way.
+<P>
+The following program <TT>loop.c</tt> is a trivial example:
+<PRE>
+#include "gc.h"
+#include &lt;assert.h&gt;
+#include &lt;stdio.h&gt;
+
+int main()
+{
+  int i;
+
+  GC_INIT();   /* Optional on Linux/X86; see below.  */
+  for (i = 0; i < 10000000; ++i)
+   {
+     int **p = (int **) GC_MALLOC(sizeof(int *));
+     int *q = (int *) GC_MALLOC_ATOMIC(sizeof(int));
+     assert(*p == 0);
+     *p = (int *) GC_REALLOC(q, 2 * sizeof(int));
+     if (i % 100000 == 0)
+       printf("Heap size = %d\n", GC_get_heap_size());
+   }
+  return 0;
+}
+</pre>
+<FONT COLOR=green>
+<H3>Interaction with the system malloc</h3>
+It is usually best not to mix garbage-collected allocation with the system
+<TT>malloc-free</tt>.  If you do, you need to be careful not to store
+pointers to the garbage-collected heap in memory allocated with the system
+<TT>malloc</tt>.
+<H3>Other Platforms</h3>
+On some other platforms it is necessary to call <TT>GC_INIT()</tt> from the main program,
+which is presumed to be part of the main executable, not a dynamic library.
+This can never hurt, and is thus generally good practice.
+
+<H3>Threads</h3>
+For a multithreaded program some more rules apply:
+<UL>
+<LI>
+Files that either allocate through the GC <I>or make thread-related calls</i>
+should first define the macro <TT>GC_THREADS</tt>, and then
+include <TT>"gc.h"</tt>.  On some platforms this will redefine some
+threads primitives, e.g. to let the collector keep track of thread creation.
+<LI>
+To take advantage of fast thread-local allocation, use the following instead
+of including <TT>gc.h</tt>:
+<PRE>
+#define GC_REDIRECT_TO_LOCAL
+#include "gc_local_alloc.h"
+</pre>
+This will cause GC_MALLOC and GC_MALLOC_ATOMIC to keep per-thread allocation
+caches, and greatly reduce the number of lock acquisitions during allocation.
+</ul>
+
+<H3>C++</h3>
+In the case of C++, you need to be especially careful not to store pointers
+to the garbage-collected heap in areas that are not traced by the collector.
+The collector includes some <A HREF="gcinterface.html">alternate interfaces</a>
+to make that easier.
+
+<H3>Debugging</h3>
+Additional debug checks can be performed by defining <TT>GC_DEBUG</tt> before
+including <TT>gc.h</tt>.  Additional options are available if the collector
+is also built with <TT>--enable-full_debug</tt> and all allocations are
+performed with <TT>GC_DEBUG</tt> defined.
+
+<H3>What if I can't rewrite/recompile my program?</h3>
+You may be able to build the collector with <TT>--enable-redirect-malloc</tt>
+and set the <TT>LD_PRELOAD</tt> environment variable to point to the resulting
+library, thus replacing the standard <TT>malloc</tt> with its garbage-collected
+counterpart.  This is rather platform dependent.  See the
+<A HREF="leak.html">leak detection documentation</a> for some more details.
+
+</font>
+
+<H2>Compiling and linking</h2>
+
+The above application <TT>loop.c</tt> test program can be compiled and linked
+with
+
+<PRE>
+cc -I/home/xyz/gc/include loop.c /home/xyz/gc/lib/libgc.a -o loop
+</pre>
+
+The <TT>-I</tt> option directs the compiler to the right include
+directory.  In this case, we list the static library
+directly on the compile line; the dynamic library could have been
+used instead, provided we arranged for the dynamic loader to find
+it, e.g. by setting <TT>LD_LIBRARY_PATH</tt>.
+
+<FONT COLOR=green>
+
+<H3>Threads</h3>
+
+On pthread platforms, you will of course also have to link with
+<TT>-lpthread</tt>,
+and compile with any thread-safety options required by your compiler.
+On some platforms, you may also need to link with <TT>-ldl</tt>
+or <TT>-lrt</tt>.
+Looking at threadlibs.c in the GC build directory
+should give you the appropriate
+list if a plain <TT>-lpthread</tt> doesn't work.
+
+</font>
+
+<H2>Running the executable</h2>
+
+The executable can of course be run normally, e.g. by typing
+
+<PRE>
+./loop
+</pre>
+
+The operation of the collector is affected by a number of environment variables.
+For example, setting <TT>GC_PRINT_STATS</tt> produces some
+GC statistics on stdout.
+See <TT>README.environment</tt> in the distribution for details.
+</body>
+</html>
index 70eb7644e68f7a79b1095db657cd61ec6e178e02..9bd9e060688f881e3b07c89681c111084a57db15 100644 (file)
 /* Newer versions of GNU/Linux define this macro.  We
  * define it similarly for any ELF systems that don't.  */
 #  ifndef ElfW
-#    if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32
-#      define ElfW(type) Elf32_##type
+#    ifdef __NetBSD__
+#      if ELFSIZE == 32
+#        define ElfW(type) Elf32_##type
+#      else
+#        define ElfW(type) Elf64_##type
+#      endif
 #    else
-#      define ElfW(type) Elf64_##type
+#      if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32
+#        define ElfW(type) Elf32_##type
+#      else
+#        define ElfW(type) Elf64_##type
+#      endif
 #    endif
 #  endif
 
index 0aa513973c96af518637ccaff28d3814575abc47..b7be1d84930be9fb4d54fd59b70572815deb8eda 100644 (file)
--- a/headers.c
+++ b/headers.c
@@ -206,7 +206,7 @@ register struct hblk * h;
 {
     hdr * result;
     
-    if (!get_index((word) h)) return(FALSE);
+    if (!get_index((word) h)) return(0);
     result = alloc_hdr();
     SET_HDR(h, result);
 #   ifdef USE_MUNMAP
index 58a2ff5428a379bc373877799378a89a8b8bcfca..2a8900913df301d265a166f820b8047708127fe4 100644 (file)
@@ -778,6 +778,7 @@ GC_API GC_PTR GC_call_with_alloc_lock
 
 /* The following routines are primarily intended for use with a        */
 /* preprocessor which inserts calls to check C pointer arithmetic.     */
+/* They indicate failure by invoking the corresponding _print_proc.    */
 
 /* Check that p and q point to the same object.                */
 /* Fail conspicuously if they don't.                           */
@@ -855,7 +856,7 @@ GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR     p));
 #   define GC_PTR_STORE(p, q) *((p) = (q))
 #endif
 
-/* Fynctions called to report pointer checking errors */
+/* Functions called to report pointer checking errors */
 GC_API void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR p, GC_PTR q));
 
 GC_API void (*GC_is_valid_displacement_print_proc)
@@ -929,7 +930,7 @@ extern void GC_thr_init();  /* Needed for Solaris/X86       */
   * no-op and the collector self-initializes.  But a number of platforms
   * make that too hard.
   */
-#if defined(sparc) || defined(__sparc)
+#if (defined(sparc) || defined(__sparc)) && defined(sun)
     /*
      * If you are planning on putting
      * the collector in a SunOS 5 dynamic library, you need to call GC_INIT()
index 87c85099381a79f872d62d99f816886f99d080e8..200f181efa6f17261b8187570389c50c96ae2814 100644 (file)
  * library, which itself was derived from the SGI STL implementation.
  */
 
-#include "gc.h"        // For size_t
+#ifndef GC_ALLOCATOR_H
+
+#define GC_ALLOCATOR_H
+
+#include "gc.h"
+
+#if defined(__GNUC__)
+#  define GC_ATTR_UNUSED __attribute__((unused))
+#else
+#  define GC_ATTR_UNUSED
+#endif
 
 /* First some helpers to allow us to dispatch on whether or not a type
  * is known to be pointerfree.
@@ -118,7 +128,7 @@ public:
   }
 
   // __p is not permitted to be a null pointer.
-  void deallocate(pointer __p, size_type GC_n)
+  void deallocate(pointer __p, size_type GC_ATTR_UNUSED GC_n)
     { GC_FREE(__p); }
 
   size_type max_size() const throw()
@@ -194,7 +204,7 @@ public:
   }
 
   // __p is not permitted to be a null pointer.
-  void deallocate(pointer __p, size_type GC_n)
+  void deallocate(pointer __p, size_type GC_ATTR_UNUSED GC_n)
     { GC_FREE(__p); }
 
   size_type max_size() const throw()
@@ -230,3 +240,4 @@ inline bool operator!=(const traceable_allocator<GC_T1>&, const traceable_alloca
   return false;
 }
 
+#endif /* GC_ALLOCATOR_H */
index 4aaca2d3c60cff3da3d44e2eabc21faf30eb26c9..d8d31141262d7d2f452f4c9f323cca1cdd782ac8 100644 (file)
 # endif
 #endif /* GC_THREADS */
 
-#if defined(GC_THREADS) && !defined(GC_PTHREADS) && defined(MSWIN32)
+#if defined(GC_THREADS) && !defined(GC_PTHREADS) && \
+    (defined(_WIN32) || defined(_MSC_VER) || defined(__CYGWIN__) \
+     || defined(__MINGW32__) || defined(__BORLANDC__) \
+     || defined(_WIN32_WCE))
 # define GC_WIN32_THREADS
 #endif
 
index b9576912476218ad5e8bec089ff04d7a165f221e..08dd8ea247b1083543c2a2d889d7d2bc8bb1de64 100644 (file)
@@ -550,7 +550,7 @@ extern GC_warn_proc GC_current_warn_proc;
 
 #define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2)
 #define MAXOBJBYTES ((word)CPP_MAXOBJBYTES)
-#define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_HBLKSIZE/2)
+#define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_MAXOBJBYTES)
 #define MAXOBJSZ ((word)CPP_MAXOBJSZ)
                
 # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)
@@ -578,7 +578,7 @@ extern GC_warn_proc GC_current_warn_proc;
 # else
 #       define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n)
 # endif
-# define SMALL_OBJ(bytes) ((bytes) < (MAXOBJBYTES - EXTRA_BYTES))
+# define SMALL_OBJ(bytes) ((bytes) <= (MAXOBJBYTES - EXTRA_BYTES))
 # define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES)
 # ifndef MIN_WORDS
     /* MIN_WORDS is the size of the smallest allocated object. */
@@ -938,11 +938,11 @@ struct _GC_arrays {
        char _valid_offsets[VALID_OFFSET_SZ];
                                /* GC_valid_offsets[i] == TRUE ==> i    */
                                /* is registered as a displacement.     */
-#      define OFFSET_VALID(displ) \
-         (GC_all_interior_pointers || GC_valid_offsets[displ])
        char _modws_valid_offsets[sizeof(word)];
                                /* GC_valid_offsets[i] ==>                */
                                /* GC_modws_valid_offsets[i%sizeof(word)] */
+#   define OFFSET_VALID(displ) \
+         (GC_all_interior_pointers || GC_valid_offsets[displ])
 # ifdef STUBBORN_ALLOC
     page_hash_table _changed_pages;
         /* Stubborn object pages that were changes since last call to  */
index 734bd8552ce924895ad6b25e53331b869371175f..94b446b6796cae8ee56b03483f2027cc7006f39a 100644 (file)
 #   define I386
 #   define mach_type_known
 # endif
+# if defined(__NetBSD__) && defined(__x86_64__)
+#    define X86_64
+#    define mach_type_known
+# endif
 # if defined(bsdi) && (defined(i386) || defined(__i386__))
 #    define I386
 #    define BSDI
 #   ifdef OPENBSD
 #      define OS_TYPE "OPENBSD"
 #      define HEURISTIC2
-       extern char etext[];
-#      define DATASTART ((ptr_t)(etext))
+#      ifdef __ELF__
+#        define DATASTART GC_data_start
+#        define DYNAMIC_LOADING
+#      else
+         extern char etext[];
+#        define DATASTART ((ptr_t)(etext))
+#       endif
+#       define USE_GENERIC_PUSH_REGS
 #   endif
 #   ifdef NETBSD
 #      define OS_TYPE "NETBSD"
          extern char etext[];
 #        define DATASTART ((ptr_t)(etext))
 #       endif
+#      define USE_GENERIC_PUSH_REGS
 #   endif
 #   ifdef LINUX
 #       define OS_TYPE "LINUX"
 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
 #       endif
 #      ifdef USE_I686_PREFETCH
+         /* FIXME: Thus should use __builtin_prefetch, but we'll leave that    */
+         /* for the next rtelease.                                             */
 #        define PREFETCH(x) \
            __asm__ __volatile__ ("     prefetchnta     %0": : "m"(*(char *)(x)))
            /* Empirically prefetcht0 is much more effective at reducing        */
 #       ifdef __GNUC__
 #        ifndef __INTEL_COMPILER
 #          define PREFETCH(x) \
-             __asm__ ("        lfetch  [%0]": : "r"((void *)(x)))
+             __asm__ ("        lfetch  [%0]": : "r"(x))
 #          define PREFETCH_FOR_WRITE(x) \
-             __asm__ ("        lfetch.excl     [%0]": : "r"((void *)(x)))
+             __asm__ ("        lfetch.excl     [%0]": : "r"(x))
 #          define CLEAR_DOUBLE(x) \
              __asm__ ("        stf.spill       [%0]=f0": : "r"((void *)(x)))
 #        else
 #           include <ia64intrin.h>
 #          define PREFETCH(x) \
-             __lfetch(__lfhint_none, (void*)(x))
+             __lfetch(__lfhint_none, (x))
 #          define PREFETCH_FOR_WRITE(x) \
-             __lfetch(__lfhint_nta,  (void*)(x))
+             __lfetch(__lfhint_nta,  (x))
 #          define CLEAR_DOUBLE(x) \
              __stf_spill((void *)(x), 0)
 #        endif // __INTEL_COMPILER
             extern int etext[];
 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
 #       endif
-#      define PREFETCH(x) \
-         __asm__ __volatile__ ("       prefetch        %0": : "m"(*(char *)(x)))
-#      define PREFETCH_FOR_WRITE(x) \
-         __asm__ __volatile__ ("       prefetchw       %0": : "m"(*(char *)(x)))
+#       if defined(__GNUC__) && __GNUC >= 3
+#          define PREFETCH(x) __builtin_prefetch((x), 0, 0)
+#          define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
+#      endif
+#   endif
+#   ifdef NETBSD
+#      define OS_TYPE "NETBSD"
+#      ifdef __ELF__
+#          define DYNAMIC_LOADING
+#      endif
+#      define HEURISTIC2
+       extern char etext[];
+#      define SEARCH_FOR_DATA_START
 #   endif
 # endif
 
 #   define SUNOS5SIGS
 # endif
 
+# if defined(FREEBSD) && (__FreeBSD__ >= 4)
+#   define SUNOS5SIGS
+# endif
+
 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
            || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
            || defined(DGUX) || defined(BSD) || defined(SUNOS4) \
diff --git a/ltconfig b/ltconfig
deleted file mode 100644 (file)
index 962057f..0000000
--- a/ltconfig
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-# I could find no versions of autoconf that don't invoke ltconfig, but
-# libtool no longer includes an ltconfig.  Yuch.
diff --git a/mark.c b/mark.c
index 4b654683d9d7b57a6f33932f55ec2afaac79134b..c645bc0eeecc50644936b20adb48db6cf9e99a94 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -684,7 +684,7 @@ mse * mark_stack_limit;
               current = *current_p;
              FIXUP_POINTER(current);
              if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
-               PREFETCH(current);
+               PREFETCH((ptr_t)current);
                 HC_PUSH_CONTENTS((ptr_t)current, mark_stack_top,
                              mark_stack_limit, current_p, exit1);
              }
@@ -760,7 +760,7 @@ mse * mark_stack_limit;
          FIXUP_POINTER(deferred);
          limit = (word *)((char *)limit - ALIGNMENT);
          if ((ptr_t)deferred >= least_ha && (ptr_t)deferred <  greatest_ha) {
-           PREFETCH(deferred);
+           PREFETCH((ptr_t)deferred);
            break;
          }
          if (current_p > limit) goto next_object;
@@ -770,7 +770,7 @@ mse * mark_stack_limit;
          FIXUP_POINTER(deferred);
          limit = (word *)((char *)limit - ALIGNMENT);
          if ((ptr_t)deferred >= least_ha && (ptr_t)deferred <  greatest_ha) {
-           PREFETCH(deferred);
+           PREFETCH((ptr_t)deferred);
            break;
          }
          if (current_p > limit) goto next_object;
@@ -787,7 +787,7 @@ mse * mark_stack_limit;
         if ((ptr_t)current >= least_ha && (ptr_t)current <  greatest_ha) {
          /* Prefetch the contents of the object we just pushed.  It's  */
          /* likely we will need them soon.                             */
-         PREFETCH(current);
+         PREFETCH((ptr_t)current);
           HC_PUSH_CONTENTS((ptr_t)current, mark_stack_top,
                           mark_stack_limit, current_p, exit2);
         }
@@ -1739,7 +1739,7 @@ register hdr * hhdr;
 {
     register int sz = hhdr -> hb_sz;
     
-    if (sz < MAXOBJSZ) {
+    if (sz <= MAXOBJSZ) {
          return(GC_page_was_dirty(h));
     } else {
         register ptr_t p = (ptr_t)h;
index 1aa2c7a125320a485ea1d545b1fc58234c10b971..e5580e4ca218d9770f7dcf171bf4cc61420852c2 100644 (file)
@@ -104,7 +104,7 @@ ptr_t ofl;
     p[3] = 0;
     p += 4;
     for (; p < lim; p += 4) {
-       PREFETCH_FOR_WRITE(p+64);
+       PREFETCH_FOR_WRITE((ptr_t)(p+64));
         p[0] = (word)(p-4);
         p[1] = 0;
        CLEAR_DOUBLE(p+2);
@@ -142,7 +142,7 @@ ptr_t ofl;
     p[4] = (word)p;
     p += 8;
     for (; p < lim; p += 8) {
-       PREFETCH_FOR_WRITE(p+64);
+       PREFETCH_FOR_WRITE((ptr_t)(p+64));
         p[0] = (word)(p-4);
         p[4] = (word)p;
     };
@@ -171,10 +171,10 @@ ptr_t list;
   /* If we were more serious about it, these should go inside  */
   /* the loops.  But write prefetches usually don't seem to    */
   /* matter much.                                              */
-    PREFETCH_FOR_WRITE((char *)h);
-    PREFETCH_FOR_WRITE((char *)h + 128);
-    PREFETCH_FOR_WRITE((char *)h + 256);
-    PREFETCH_FOR_WRITE((char *)h + 378);
+    PREFETCH_FOR_WRITE((ptr_t)h);
+    PREFETCH_FOR_WRITE((ptr_t)h + 128);
+    PREFETCH_FOR_WRITE((ptr_t)h + 256);
+    PREFETCH_FOR_WRITE((ptr_t)h + 378);
   /* Handle small objects sizes more efficiently.  For larger objects  */
   /* the difference is less significant.                               */
 #  ifndef SMALL_CONFIG
index cb32bdd0f159dc11fdadcf411e57b484dd32d8f7..21d05635ab81740ddfcc43393be384d09d241c64 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
 
 #ifdef UNIX_LIKE
 # include <fcntl.h>
-# ifdef SUNOS5SIGS
+# if defined(SUNOS5SIGS) && !defined(FREEBSD)
 #  include <sys/siginfo.h>
 # endif
   /* Define SETJMP and friends to be the version that restores */
@@ -2192,7 +2192,7 @@ GC_bool is_ptrfree;
     /* Using vm_protect (mach syscall) over mprotect (BSD syscall) seems to
        decrease the likelihood of some of the problems described below. */
     #include <mach/vm_map.h>
-    extern mach_port_t GC_task_self;
+    static mach_port_t GC_task_self;
     #define PROTECT(addr,len) \
         if(vm_protect(GC_task_self,(vm_address_t)(addr),(vm_size_t)(len), \
                 FALSE,VM_PROT_READ) != KERN_SUCCESS) { \
@@ -2225,9 +2225,9 @@ GC_bool is_ptrfree;
 # endif /* !DARWIN */
 # endif /* MSWIN32 || MSWINCE || DARWIN */
 
-#if defined(SUNOS4) || defined(FREEBSD)
+#if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
     typedef void (* SIG_PF)();
-#endif /* SUNOS4 || FREEBSD */
+#endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */
 
 #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
     || defined(HURD)
@@ -2254,13 +2254,13 @@ GC_bool is_ptrfree;
 #endif /* IRIX5 || OSF1 || HURD */
 
 #if defined(SUNOS5SIGS)
-# ifdef HPUX
-#   define SIGINFO __siginfo
+# if defined(HPUX) || defined(FREEBSD)
+#   define SIGINFO_T siginfo_t
 # else
-#   define SIGINFO siginfo
+#   define SIGINFO_T struct siginfo
 # endif
 # ifdef __STDC__
-    typedef void (* REAL_SIG_PF)(int, struct SIGINFO *, void *);
+    typedef void (* REAL_SIG_PF)(int, SIGINFO_T *, void *);
 # else
     typedef void (* REAL_SIG_PF)();
 # endif
@@ -2280,8 +2280,11 @@ GC_bool is_ptrfree;
 #   if defined(ALPHA) || defined(M68K)
       typedef void (* REAL_SIG_PF)(int, int, s_c *);
 #   else
-#     if defined(IA64) || defined(HP_PA)
+#     if defined(IA64) || defined(HP_PA) || defined(X86_64)
         typedef void (* REAL_SIG_PF)(int, siginfo_t *, s_c *);
+       /* FIXME:                                                 */
+       /* According to SUSV3, the last argument should have type */
+       /* void * or ucontext_t *                                 */
 #     else
         typedef void (* REAL_SIG_PF)(int, s_c);
 #     endif
@@ -2356,7 +2359,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 
 /*ARGSUSED*/
 #if !defined(DARWIN)
-# if defined (SUNOS4) || defined(FREEBSD)
+# if defined (SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
     void GC_write_fault_handler(sig, code, scp, addr)
     int sig, code;
     struct sigcontext *scp;
@@ -2371,7 +2374,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #     define SIG_OK (sig == SIGBUS)
 #     define CODE_OK (code == BUS_PAGE_FAULT)
 #   endif
-# endif /* SUNOS4 || FREEBSD */
+# endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */
 
 # if defined(IRIX5) || defined(OSF1) || defined(HURD)
 #   include <errno.h>
@@ -2394,7 +2397,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #   if defined(ALPHA) || defined(M68K)
       void GC_write_fault_handler(int sig, int code, s_c * sc)
 #   else
-#     if defined(IA64) || defined(HP_PA)
+#     if defined(IA64) || defined(HP_PA) || defined(X86_64)
         void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
 #     else
 #       if defined(ARM32)
@@ -2413,11 +2416,11 @@ SIG_PF GC_old_segv_handler;     /* Also old MSWIN32 ACCESS_VIOLATION filter */
 
 # if defined(SUNOS5SIGS)
 #  ifdef __STDC__
-    void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
+    void GC_write_fault_handler(int sig, SIGINFO_T *scp, void * context)
 #  else
     void GC_write_fault_handler(sig, scp, context)
     int sig;
-    struct SIGINFO *scp;
+    SIGINFO_T *scp;
     void * context;
 #  endif
 #   ifdef HPUX
@@ -2428,9 +2431,14 @@ SIG_PF GC_old_segv_handler;      /* Also old MSWIN32 ACCESS_VIOLATION filter */
                     || (scp -> si_code == SEGV_UNKNOWN) \
                     || (scp -> si_code == BUS_OBJERR)
 #   else
-#     define SIG_OK (sig == SIGSEGV)
-#     define CODE_OK (scp -> si_code == SEGV_ACCERR)
-#   endif
+#     ifdef FREEBSD
+#       define SIG_OK (sig == SIGBUS)
+#       define CODE_OK (scp -> si_code == BUS_PAGE_FAULT)
+#     else
+#       define SIG_OK (sig == SIGSEGV)
+#       define CODE_OK (scp -> si_code == SEGV_ACCERR)
+#     endif
+#   endif    
 # endif /* SUNOS5SIGS */
 
 # if defined(MSWIN32) || defined(MSWINCE)
@@ -2455,7 +2463,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
        char * addr = (char *) (scp -> si_addr);
 #   endif
 #   ifdef LINUX
-#     if defined(I386) || defined (X86_64)
+#     if defined(I386)
        char * addr = (char *) (sc.cr2);
 #     else
 #      if defined(M68K)
@@ -2490,7 +2498,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #        ifdef ALPHA
             char * addr = get_fault_addr(sc);
 #        else
-#          if defined(IA64) || defined(HP_PA)
+#          if defined(IA64) || defined(HP_PA) || defined(X86_64)
              char * addr = si -> si_addr;
              /* I believe this is claimed to work on all platforms for */
              /* Linux 2.3.47 and later.  Hopefully we don't have to    */
@@ -2533,6 +2541,10 @@ SIG_PF GC_old_segv_handler;      /* Also old MSWIN32 ACCESS_VIOLATION filter */
            in_allocd_block = (HDR(addr) != 0);
 #      endif
         if (!in_allocd_block) {
+           /* FIXME - We should make sure that we invoke the   */
+           /* old handler with the appropriate calling         */
+           /* sequence, which often depends on SA_SIGINFO.     */
+
            /* Heap blocks now begin and end on page boundaries */
             SIG_PF old_handler;
             
@@ -2549,11 +2561,17 @@ SIG_PF GC_old_segv_handler;     /* Also old MSWIN32 ACCESS_VIOLATION filter */
                    return(EXCEPTION_CONTINUE_SEARCH);
 #              endif
             } else {
-#              if defined (SUNOS4) || defined(FREEBSD)
+#              if defined (SUNOS4) \
+                    || (defined(FREEBSD) && !defined(SUNOS5SIGS))
                    (*old_handler) (sig, code, scp, addr);
                    return;
 #              endif
 #              if defined (SUNOS5SIGS)
+                    /*
+                     * FIXME: For FreeBSD, this code should check if the 
+                     * old signal handler used the traditional BSD style and
+                     * if so call it using that style.
+                     */
                    (*(REAL_SIG_PF)old_handler) (sig, scp, context);
                    return;
 #              endif
@@ -2561,7 +2579,7 @@ SIG_PF GC_old_segv_handler;       /* Also old MSWIN32 ACCESS_VIOLATION filter */
 #                  if defined(ALPHA) || defined(M68K)
                        (*(REAL_SIG_PF)old_handler) (sig, code, sc);
 #                  else 
-#                    if defined(IA64) || defined(HP_PA)
+#                    if defined(IA64) || defined(HP_PA) || defined(X86_64)
                        (*(REAL_SIG_PF)old_handler) (sig, si, scp);
 #                    else
                        (*(REAL_SIG_PF)old_handler) (sig, sc);
@@ -2655,7 +2673,8 @@ void GC_dirty_init()
       struct sigaction act, oldact;
       /* We should probably specify SA_SIGINFO for Linux, and handle   */
       /* the different architectures more uniformly.                   */
-#     if defined(IRIX5) || defined(LINUX) || defined(OSF1) || defined(HURD)
+#     if defined(IRIX5) || defined(LINUX) && !defined(X86_64) \
+        || defined(OSF1) || defined(HURD)
        act.sa_flags    = SA_RESTART;
         act.sa_handler  = (SIG_PF)GC_write_fault_handler;
 #     else
@@ -2678,7 +2697,7 @@ void GC_dirty_init()
         GC_err_printf0("Page size not multiple of HBLKSIZE\n");
         ABORT("Page size not multiple of HBLKSIZE");
     }
-#   if defined(SUNOS4) || defined(FREEBSD)
+#   if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
       GC_old_bus_handler = signal(SIGBUS, GC_write_fault_handler);
       if (GC_old_bus_handler == SIG_IGN) {
         GC_err_printf0("Previously ignored bus error!?");
@@ -2702,13 +2721,13 @@ void GC_dirty_init()
 #      endif
       }
 #   endif
-#   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \
-       || defined(OSF1) || defined(HURD)
+#   if (defined(SUNOS5SIGS) && !defined(FREEBSD)) || defined(IRIX5) \
+       || defined(LINUX) || defined(OSF1) || defined(HURD)
       /* SUNOS5SIGS includes HPUX */
 #     if defined(GC_IRIX_THREADS)
        sigaction(SIGSEGV, 0, &oldact);
        sigaction(SIGSEGV, &act, 0);
-#     else
+#     else 
        {
          int res = sigaction(SIGSEGV, &act, &oldact);
          if (res != 0) ABORT("Sigaction failed");
@@ -2734,8 +2753,9 @@ void GC_dirty_init()
          GC_err_printf0("Replaced other SIGSEGV handler\n");
 #       endif
       }
-#   endif
-#   if defined(HPUX) || defined(LINUX) || defined(HURD)
+#   endif /* (SUNOS5SIGS && !FREEBSD) || IRIX5 || LINUX || OSF1 || HURD */
+#   if defined(HPUX) || defined(LINUX) || defined(HURD) \
+      || (defined(FREEBSD) && defined(SUNOS5SIGS))
       sigaction(SIGBUS, &act, &oldact);
       GC_old_bus_handler = oldact.sa_handler;
       if (GC_old_bus_handler == SIG_IGN) {
@@ -2747,7 +2767,7 @@ void GC_dirty_init()
          GC_err_printf0("Replaced other SIGBUS handler\n");
 #       endif
       }
-#   endif /* HPUX || LINUX || HURD */
+#   endif /* HPUX || LINUX || HURD || (FREEBSD && SUNOS5SIGS) */
 #   if defined(MSWIN32)
       GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
       if (GC_old_segv_handler != NULL) {
@@ -3032,7 +3052,7 @@ word n;
 #include <sys/procfs.h>
 #include <sys/stat.h>
 
-#define INITIAL_BUF_SZ 4096
+#define INITIAL_BUF_SZ 16384
 word GC_proc_buf_size = INITIAL_BUF_SZ;
 char *GC_proc_buf;
 
@@ -3146,7 +3166,7 @@ int dummy;
                 GC_proc_buf = bufp = new_buf;
                 GC_proc_buf_size = new_size;
             }
-            if (syscall(SYS_read, GC_proc_fd, bufp, GC_proc_buf_size) <= 0) {
+            if (READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) {
                 WARN("Insufficient space for /proc read\n", 0);
                 /* Punt:       */
                memset(GC_grungy_pages, 0xff, sizeof (page_hash_table));
@@ -3367,8 +3387,6 @@ extern kern_return_t exception_raise_state_identity(
 
 #define MAX_EXCEPTION_PORTS 16
 
-static mach_port_t GC_task_self;
-
 static struct {
     mach_msg_type_number_t count;
     exception_mask_t      masks[MAX_EXCEPTION_PORTS];
index 1cdda21a760c10c1ef13c98b962fafc2af91452a..832c49ca81e53d6173deba6dd190fd0361f0d694 100644 (file)
@@ -39,6 +39,34 @@ void GC_print_sig_mask()
 
 #endif
 
+/* Remove the signals that we want to allow in thread stopping         */
+/* handler from a set.                                         */
+void GC_remove_allowed_signals(sigset_t *set)
+{
+#   ifdef NO_SIGNALS
+      if (sigdelset(set, SIGINT) != 0
+         || sigdelset(set, SIGQUIT) != 0
+         || sigdelset(set, SIGABRT) != 0
+         || sigdelset(set, SIGTERM) != 0) {
+        ABORT("sigdelset() failed");
+      }
+#   endif
+
+#   ifdef MPROTECT_VDB
+      /* Handlers write to the thread structure, which is in the heap, */
+      /* and hence can trigger a protection fault.                     */
+      if (sigdelset(set, SIGSEGV) != 0
+#        ifdef SIGBUS
+           || sigdelset(set, SIGBUS) != 0
+#        endif
+         ) {
+        ABORT("sigdelset() failed");
+      }
+#   endif
+}
+
+static sigset_t suspend_handler_mask;
+
 word GC_stop_count;    /* Incremented at the beginning of GC_stop_world. */
 
 #ifdef GC_OSF1_THREADS
@@ -78,7 +106,6 @@ void GC_suspend_handler(int sig)
     int dummy;
     pthread_t my_thread = pthread_self();
     GC_thread me;
-    sigset_t mask;
 #   ifdef PARALLEL_MARK
        word my_mark_no = GC_mark_no;
        /* Marker can't proceed until we acknowledge.  Thus this is     */
@@ -125,17 +152,9 @@ void GC_suspend_handler(int sig)
     /* this thread a SIG_THR_RESTART signal.                   */
     /* SIG_THR_RESTART should be masked at this point.  Thus there     */
     /* is no race.                                             */
-    if (sigfillset(&mask) != 0) ABORT("sigfillset() failed");
-    if (sigdelset(&mask, SIG_THR_RESTART) != 0) ABORT("sigdelset() failed");
-#   ifdef NO_SIGNALS
-      if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
-      if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
-      if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
-      if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
-#   endif
     do {
            me->stop_info.signal = 0;
-           sigsuspend(&mask);             /* Wait for signal */
+           sigsuspend(&suspend_handler_mask);        /* Wait for signal */
     } while (me->stop_info.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   */
@@ -417,16 +436,9 @@ void GC_stop_init() {
     if (sigfillset(&act.sa_mask) != 0) {
        ABORT("sigfillset() failed");
     }
-#   ifdef NO_SIGNALS
-      if (sigdelset(&act.sa_mask, SIGINT) != 0
-         || sigdelset(&act.sa_mask, SIGQUIT != 0)
-         || sigdelset(&act.sa_mask, SIGABRT != 0)
-         || sigdelset(&act.sa_mask, SIGTERM != 0)) {
-        ABORT("sigdelset() failed");
-      }
-#   endif
-
-    /* SIG_THR_RESTART is unmasked by the handler when necessary.      */
+    GC_remove_allowed_signals(&act.sa_mask);
+    /* SIG_THR_RESTART is set in the resulting mask.           */
+    /* It is unmasked by the handler when necessary.           */
     act.sa_handler = GC_suspend_handler;
     if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
        ABORT("Cannot set SIG_SUSPEND handler");
@@ -437,6 +449,12 @@ void GC_stop_init() {
        ABORT("Cannot set SIG_THR_RESTART handler");
     }
 
+    /* Inititialize suspend_handler_mask. It excludes SIG_THR_RESTART. */
+      if (sigfillset(&suspend_handler_mask) != 0) ABORT("sigfillset() failed");
+      GC_remove_allowed_signals(&suspend_handler_mask);
+      if (sigdelset(&suspend_handler_mask, SIG_THR_RESTART) != 0)
+         ABORT("sigdelset() failed");
+
     /* Check for GC_RETRY_SIGNALS.     */
       if (0 != GETENV("GC_RETRY_SIGNALS")) {
          GC_retry_signals = TRUE;
index bae77193593f5e963ccd7b1531f3bb774840a802..1e43d0904f9a53953b2027acd95f4265888a1701 100644 (file)
  * Modified by Peter C. for Solaris Posix Threads.
  */
 
-# if defined(GC_SOLARIS_PTHREADS)
+# if defined(GC_SOLARIS_PTHREADS) || defined(GC_THREADS)
 # include "private/gc_priv.h"
+# endif
+# if defined(GC_SOLARIS_PTHREADS)
 # include <pthread.h>
 # include <thread.h>
 # include <signal.h>
index 5f05b19e008040b208a691864ad3e31c6125e047..0a07690a27aa035d121748fdb4d06feb0e846003 100644 (file)
  */
 /* Boehm, September 14, 1994 4:44 pm PDT */
 
-# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS)
+# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS) \
+     || defined(GC_THREADS)
+#   include "private/gc_priv.h"
+# endif
 
-# include "private/gc_priv.h"
+# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS)
 # include "private/solaris_threads.h"
 # include <thread.h>
 # include <synch.h>
@@ -786,6 +789,7 @@ void GC_thr_init(void)
 {
     GC_thread t;
     thread_t tid;
+    int ret;
 
     if (GC_thr_initialized)
            return;
@@ -803,9 +807,11 @@ void GC_thr_init(void)
       t = GC_new_thread(thr_self());
       t -> stack_size = 0;
       t -> flags = DETACHED | CLIENT_OWNS_STACK;
-    if (thr_create(0 /* stack */, 0 /* stack_size */, GC_thr_daemon,
-                  0 /* arg */, THR_DETACHED | THR_DAEMON,
-                  &tid /* thread_id */) != 0) {
+    ret = thr_create(0 /* stack */, 0 /* stack_size */, GC_thr_daemon,
+                    0 /* arg */, THR_DETACHED | THR_DAEMON,
+                    &tid /* thread_id */);
+    if (ret != 0) {
+       GC_err_printf1("Thr_create returned %ld\n", ret);
        ABORT("Cant fork daemon");
     }
     thr_setprio(tid, 126);
diff --git a/tests/middle.c b/tests/middle.c
new file mode 100644 (file)
index 0000000..5d9360a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Test at the boundary between small and large objects.
+ * Inspired by a test case from Zoltan Varga.
+ */
+#include <gc.h>
+#include <stdio.h>
+
+int main ()
+{
+        int i;
+
+        GC_all_interior_pointers = 0;
+
+        for (i = 0; i < 20000; ++i) {
+                GC_malloc_atomic (4096);
+                GC_malloc (4096);
+       }
+        for (i = 0; i < 20000; ++i) {
+                GC_malloc_atomic (2048);
+                GC_malloc (2048);
+       }
+       printf("Final heap size is %ld\n", GC_get_heap_size());
+       return 0;
+}
+
index ccec876f7870baddbd1ea3577cb65d3b7db2dc36..e1676aadead5ced4bc2a0b183ddbf43f714b19bb 100644 (file)
@@ -1255,9 +1255,11 @@ void run_one_test()
        FAIL;
       }
       if (!TEST_FAIL_COUNT(1)) {
-#      if!(defined(RS6000) || defined(POWERPC) || defined(IA64))
+#      if!(defined(RS6000) || defined(POWERPC) || defined(IA64)) || defined(M68K)
          /* ON RS6000s function pointers point to a descriptor in the  */
          /* data segment, so there should have been no failures.       */
+         /* The same applies to IA64.  Something similar seems to      */
+         /* be going on with NetBSD/M68K.                              */
          (void)GC_printf0("GC_is_visible produced wrong failure indication\n");
          FAIL;
 #      endif
index 247d3c652ec3a71c834879a1c2989de5778308cf..264b7240cbe8d5fa88c590ed5f6e21a88d7a6c9b 100644 (file)
@@ -1,3 +1,4 @@
+# include "gc_config_macros.h"
 # include "private/gcconfig.h"
 # include <stdio.h>
 
index 3f46a40daa721bf41262f5e764272d36dccb2da8..93000c34e1656b3efb46b6277ff416f8c68c2bc8 100644 (file)
--- a/version.h
+++ b/version.h
@@ -3,7 +3,7 @@
 /* it to keep the old-style build process working.             */
 #define GC_TMP_VERSION_MAJOR 6
 #define GC_TMP_VERSION_MINOR 3
-#define GC_TMP_ALPHA_VERSION 5
+#define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA
 
 #ifndef GC_NOT_ALPHA
 #   define GC_NOT_ALPHA 0xff