]> granicus.if.org Git - gc/commitdiff
gc6.7 tarball import gc6_7
authorIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 14:55:17 +0000 (18:55 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 14:55:17 +0000 (18:55 +0400)
33 files changed:
Makefile
Makefile.am
Makefile.direct
Makefile.in
allchblk.c
alloc.c
configure
configure.in
darwin_stop_world.c
dbg_mlc.c
doc/README
doc/README.changes
doc/gcinterface.html
dyn_load.c
headers.c
include/gc.h
include/gc_config_macros.h
include/gc_cpp.h
include/gc_pthread_redirects.h
include/leak_detector.h
include/private/gc_locks.h
include/private/gc_pmark.h
include/private/gc_priv.h
include/private/gcconfig.h
malloc.c
mark.c
misc.c
os_dep.c
powerpc_darwin_mach_dep.s
pthread_stop_world.c
pthread_support.c
threadlibs.c
version.h

index 1f03b511c3b298c6fc71abcdbfc3bc2d090d944e..462a54fe70914cf17611eef3f14c83844ac8da34 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -144,9 +144,9 @@ HOSTCFLAGS=$(CFLAGS)
 # -DJAVA_FINALIZATION makes it somewhat safer to finalize objects out of
 #   order by specifying a nonstandard finalization mark procedure  (see
 #   finalize.c).  Objects reachable from finalizable objects will be marked
-#   in a sepearte postpass, and hence their memory won't be reclaimed.
+#   in a separate postpass, and hence their memory won't be reclaimed.
 #   Not recommended unless you are implementing a language that specifies
-#   these semantics.  Since 5.0, determines only only the initial value
+#   these semantics.  Since 5.0, determines only the initial value
 #   of GC_java_finalization variable.
 # -DFINALIZE_ON_DEMAND causes finalizers to be run only in response
 #   to explicit GC_invoke_finalizers() calls.
index 89594f9d692dc6bc7dd54ddf42baf5ad7a905bfc..1ff290ef4b50ce414f8c5365a212f87316ac7c44 100644 (file)
@@ -95,7 +95,7 @@ gctest_LDADD = ./libgc.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
 test_cpp_SOURCES = tests/test_cpp.cc
 test_cpp_LDADD = ./libgc.la ./libgccpp.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
 
-TESTS = gctest $(extra_checks)
+TESTS = $(check_PROGRAMS)
 
 ## FIXME: relies on internal code generated by automake.
 all_objs = @addobjs@ $(libgc_la_OBJECTS)
index 1f03b511c3b298c6fc71abcdbfc3bc2d090d944e..462a54fe70914cf17611eef3f14c83844ac8da34 100644 (file)
@@ -144,9 +144,9 @@ HOSTCFLAGS=$(CFLAGS)
 # -DJAVA_FINALIZATION makes it somewhat safer to finalize objects out of
 #   order by specifying a nonstandard finalization mark procedure  (see
 #   finalize.c).  Objects reachable from finalizable objects will be marked
-#   in a sepearte postpass, and hence their memory won't be reclaimed.
+#   in a separate postpass, and hence their memory won't be reclaimed.
 #   Not recommended unless you are implementing a language that specifies
-#   these semantics.  Since 5.0, determines only only the initial value
+#   these semantics.  Since 5.0, determines only the initial value
 #   of GC_java_finalization variable.
 # -DFINALIZE_ON_DEMAND causes finalizers to be run only in response
 #   to explicit GC_invoke_finalizers() calls.
index c89c84cb7fe288e655cd24ddce384d0f5101c4e8..8f3f4924704080d469b9e51ff76e4eef443951a1 100644 (file)
@@ -359,7 +359,7 @@ gctest_SOURCES = tests/test.c
 gctest_LDADD = ./libgc.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
 test_cpp_SOURCES = tests/test_cpp.cc
 test_cpp_LDADD = ./libgc.la ./libgccpp.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
-TESTS = gctest $(extra_checks)
+TESTS = $(check_PROGRAMS)
 all_objs = @addobjs@ $(libgc_la_OBJECTS)
 @COMPILER_XLC_FALSE@ASM_CPP_OPTIONS = -Wp,-P -x assembler-with-cpp
 @COMPILER_XLC_TRUE@ASM_CPP_OPTIONS = 
index 1a1efc6b91b920dcdacdf1582394eb63ee461443..3e020a8d76d2787ff5be9ba751f2da735791fa7a 100644 (file)
@@ -529,7 +529,7 @@ int index;  /* Index of free list */
                                /* free blocks in GC_add_to_fl.         */
 #     endif
 #   ifdef USE_MUNMAP
-      hhdr -> hb_last_reclaimed = GC_gc_no;
+      hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #   endif
     hhdr -> hb_sz = h_size;
     GC_add_to_fl(h, hhdr);
@@ -793,7 +793,7 @@ signed_word size;
     GC_remove_counts(hbp, (word)size);
     hhdr->hb_sz = size;
 #   ifdef USE_MUNMAP
-      hhdr -> hb_last_reclaimed = GC_gc_no;
+      hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #   endif
     
     /* Check for duplicate deallocation in the easy case */
@@ -821,7 +821,7 @@ signed_word size;
          GC_remove_from_fl(prevhdr, FL_UNKNOWN);
          prevhdr -> hb_sz += hhdr -> hb_sz;
 #        ifdef USE_MUNMAP
-           prevhdr -> hb_last_reclaimed = GC_gc_no;
+           prevhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #        endif
          GC_remove_header(hbp);
          hbp = prev;
diff --git a/alloc.c b/alloc.c
index 9b4869f91b28066cbe3dc933adf7f9e97941c6ab..9b91e6c509aff9aa33fa143b95506eaed501c172 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -206,7 +206,7 @@ word GC_adj_words_allocd()
        /* had been reallocated this round. Finalization is user        */
        /* visible progress.  And if we don't count this, we have       */
        /* stability problems for programs that finalize all objects.   */
-    if ((GC_words_wasted >> 3) < result)
+    if ((signed_word)(GC_words_wasted >> 3) < result)
         result += GC_words_wasted;
        /* This doesn't reflect useful work.  But if there is lots of   */
        /* new fragmentation, the same is probably true of the heap,    */
@@ -402,7 +402,7 @@ GC_stop_func stop_func;
 /*
  * Perform n units of garbage collection work.  A unit is intended to touch
  * roughly GC_RATE pages.  Every once in a while, we do more than that.
- * This needa to be a fairly large number with our current incremental
+ * This needs to be a fairly large number with our current incremental
  * GC strategy, since otherwise we allocate too much during GC, and the
  * cleanup gets expensive.
  */
index 059365da1bbfaf43385437432351b44ca2f41b61..372c8a8e01386dd58433474dd8d1f661272229e5 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.59 for gc 6.6.
+# Generated by GNU Autoconf 2.59 for gc 6.7.
 #
 # Report bugs to <Hans.Boehm@hp.com>.
 #
@@ -429,8 +429,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='gc'
 PACKAGE_TARNAME='gc'
-PACKAGE_VERSION='6.6'
-PACKAGE_STRING='gc 6.6'
+PACKAGE_VERSION='6.7'
+PACKAGE_STRING='gc 6.7'
 PACKAGE_BUGREPORT='Hans.Boehm@hp.com'
 
 ac_unique_file="gcj_mlc.c"
@@ -956,7 +956,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures gc 6.6 to adapt to many kinds of systems.
+\`configure' configures gc 6.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1023,7 +1023,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of gc 6.6:";;
+     short | recursive ) echo "Configuration of gc 6.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1167,7 +1167,7 @@ fi
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-gc configure 6.6
+gc configure 6.7
 generated by GNU Autoconf 2.59
 
 Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1181,7 +1181,7 @@ cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by gc $as_me 6.6, which was
+It was created by gc $as_me 6.7, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
@@ -1953,7 +1953,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='gc'
- VERSION='6.6'
+ VERSION='6.7'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4041,6 +4041,23 @@ _ACEOF
        INCLUDES="$INCLUDES -pthread"
        THREADDLLIBS=-pthread
        ;;
+     *-*-netbsd*)
+       { echo "$as_me:$LINENO: WARNING: \"Only on NetBSD 2.0 or later.\"" >&5
+echo "$as_me: WARNING: \"Only on NetBSD 2.0 or later.\"" >&2;}
+       cat >>confdefs.h <<\_ACEOF
+#define GC_NETBSD_THREADS 1
+_ACEOF
+
+       cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+       cat >>confdefs.h <<\_ACEOF
+#define _PTHREADS 1
+_ACEOF
+
+       THREADDLLIBS="-lpthread -lrt"
+       ;;
      *-*-solaris*)
        cat >>confdefs.h <<\_ACEOF
 #define GC_SOLARIS_THREADS 1
@@ -6052,7 +6069,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6055 "configure"' > conftest.$ac_ext
+  echo '#line 6072 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -6625,7 +6642,7 @@ chmod -w .
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
 compiler_c_o=no
-if { (eval echo configure:6628: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:6645: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
   # The compiler can only warn and ignore the option if not recognized
   # So say no if there are warnings
   if test -s out/conftest.err; then
@@ -8552,7 +8569,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 8555 "configure"
+#line 8572 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -8650,7 +8667,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 8653 "configure"
+#line 8670 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10272,7 +10289,7 @@ _ASBOX
 } >&5
 cat >&5 <<_CSEOF
 
-This file was extended by gc $as_me 6.6, which was
+This file was extended by gc $as_me 6.7, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -10330,7 +10347,7 @@ _ACEOF
 
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-gc config.status 6.6
+gc config.status 6.7
 configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
index d81e2eafcd2aeee586d9101ea50d24dce69bc6ba..247760c408c47fed6916823371710adb9caef32f 100644 (file)
@@ -17,7 +17,7 @@ dnl Process this file with autoconf to produce configure.
 # Initialization
 # ==============
 
-AC_INIT(gc,6.6,Hans.Boehm@hp.com) 
+AC_INIT(gc,6.7,Hans.Boehm@hp.com) 
     ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
 AC_CONFIG_SRCDIR(gcj_mlc.c)
 AC_CANONICAL_TARGET 
@@ -110,6 +110,13 @@ case "$THREADS" in
        INCLUDES="$INCLUDES -pthread"
        THREADDLLIBS=-pthread
        ;;
+     *-*-netbsd*)
+       AC_MSG_WARN("Only on NetBSD 2.0 or later.")
+       AC_DEFINE(GC_NETBSD_THREADS)
+       AC_DEFINE(_REENTRANT)
+       AC_DEFINE(_PTHREADS)
+       THREADDLLIBS="-lpthread -lrt"
+       ;;
      *-*-solaris*)
        AC_DEFINE(GC_SOLARIS_THREADS)
        AC_DEFINE(GC_SOLARIS_PTHREADS)
index 4c08b9fb098dc1f439ab3ea57398543185763f3b..665e8965493fa74906b265369049c3fb795b6093 100644 (file)
@@ -1,5 +1,7 @@
 #include "private/pthread_support.h"
 
+/* This probably needs more porting work to ppc64. */
+
 # if defined(GC_DARWIN_THREADS)
 
 /* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
@@ -36,7 +38,7 @@ unsigned long FindTopOfStack(unsigned int stack_start) {
 #   if CPP_WORDSZ == 32
       __asm__ volatile("lwz    %0,0(r1)" : "=r" (frame));
 #   else
-      __asm__ volatile("ldz    %0,0(r1)" : "=r" (frame));
+      __asm__ volatile("ld     %0,0(r1)" : "=r" (frame));
 #   endif
 # endif
   } else {
@@ -73,7 +75,13 @@ void GC_push_all_stacks() {
   GC_thread p;
   pthread_t me;
   ptr_t lo, hi;
+#if defined(POWERPC)
   ppc_thread_state_t state;
+#elif defined(I386)
+  i386_thread_state_t state;
+#else
+# error FIXME for non-x86 || ppc architectures
+#endif
   mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
   
   me = pthread_self();
@@ -93,6 +101,17 @@ void GC_push_all_stacks() {
                             &thread_state_count);
        if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
        
+#if defined(I386)
+       lo = state.esp;
+
+       GC_push_one(state.eax); 
+       GC_push_one(state.ebx); 
+       GC_push_one(state.ecx); 
+       GC_push_one(state.edx); 
+       GC_push_one(state.edi); 
+       GC_push_one(state.esi); 
+       GC_push_one(state.ebp); 
+#elif defined(POWERPC)
        lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE);
         
        GC_push_one(state.r0); 
@@ -126,6 +145,9 @@ void GC_push_all_stacks() {
        GC_push_one(state.r29); 
        GC_push_one(state.r30); 
        GC_push_one(state.r31);
+#else
+# error FIXME for non-x86 || ppc architectures
+#endif
       } /* p != me */
       if(p->flags & MAIN_THREAD)
        hi = GC_stackbottom;
@@ -247,6 +269,7 @@ void GC_push_all_stacks() {
 #     endif
       GC_push_all_stack(lo, hi); 
     } /* for(p=GC_threads[i]...) */
+    vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
 }
 #endif /* !DARWIN_DONT_PARSE_STACK */
 
@@ -390,6 +413,7 @@ void GC_stop_world()
        changes = result;
        prev_list = act_list;
        prevcount = listcount;
+        vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
       } while (changes);
       
  
@@ -461,6 +485,7 @@ void GC_start_world()
        }
       }
     }
+    vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
 #   if DEBUG_THREADS
      GC_printf0("World started\n");
 #   endif
index aacbb7a1b632e091c6a7cd97f89b587aa2bd83a6..3cabaf43767164d880ea32623aebdbcfcd8cb31d 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -14,6 +14,8 @@
  * modified is included with the above copyright notice.
  */
 
+#include <errno.h>
+#include <string.h>
 #include "private/dbg_mlc.h"
 
 void GC_default_print_heap_obj_proc();
@@ -713,6 +715,26 @@ GC_PTR p;
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
+# ifdef __STDC__
+    char *GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
+#else
+    char *GC_debug_strdup(str, s, i)
+    char *str;
+    char *s;
+    int i;
+#endif
+{
+    char *copy;
+    if (str == NULL) return NULL;
+    copy = GC_debug_malloc_atomic(strlen(str) + 1, OPT_RA s, i);
+    if (copy == NULL) {
+      errno = ENOMEM;
+      return NULL;
+    }
+    strcpy(copy, str);
+    return copy;
+}
+
 # ifdef __STDC__
     GC_PTR GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
 # else
index a19cb3021b0aa9568f3ec265e4aca5a2961606ce..46651ecbbd8d83a962a6a1dca364be9e189da620 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.6 of a conservative garbage collector for C and C++.
+This is version 6.7 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
index 97b0b684dde5b556750993056e3240d3bee1c2f5..2b6ff9ac2fc1f667e9b0f46c69f5d323ea05748b 100644 (file)
@@ -2245,6 +2245,45 @@ Since 6.5
    to Ben Hutchings for the observation and patch.)
  - Move up struct callinfo declaration to make gcc 4.0.2. happy.
 
+Since 6.6:
+ - Add "int" to Solaris "end" and "etext" declaration in gc.h.  Declared
+   the symbols with underscores and as arrays, since that's what's actually
+   used.  Perhaps this could all just be removed?  (Thanks to John Bowman.)
+ - Fixed ARM GC_test_and_set code.  (Thanks to Kazu Hirata and Paul Brook.)
+ - Added casts for assignments to hb_last_reclaimed, which truncate the
+   value.  Added a cast to GC_adj_words_allocd.  Use GetModuleHandleA
+   when retrieving a handle to kernel32.dll under win32.  (Thanks to the
+   Visual Prolog developers.)
+ - Added Tandem S-Series support.  (Thanks to Craig McDaniel.  A modified
+   version of his patch was applied, and hence breakage is probably not
+   his fault.)
+ - Remove spurious gc:: qualifier for operator delete[] in gc_cpp.h.
+   (Thanks to Hanno Boeck.)
+ - Changed a test for LINUX in config_macros.h to one for __linux__.
+ - Fix ppc 64 test_and_set code by removing it.  (Thanks to Christian
+   Thalinger.)
+ - Add prototypes for GC_finalizer_notifier and GC_thr_init.  (Thanks to
+   David Ayers.)
+ - Use ld instead of nonexistent ldz instruction in Darwin FindTopOfStack.
+   (Thanks to Andreas Tobler.)
+ - Add support for Darwin/X86.  (Thanks to Geoff Norton and the Mono
+   developers.)
+ - Merge in some recent gcc fixes.  Add ppc64 asm code.  (Thanks to Bryce
+   McKinley and other gcj developers.)
+ - Scan MEM_PRIVATE sections under Windows ME and predecessors.
+ - Interior pointers with some largish offsets into large objects could
+   be ignored, if GC_all_interior_pointers was set.  (Oddly this worked
+   correctly for stack references if it was not set.  Otherwise it failed
+   for both stack and heap references.)  Thanks to Andrew McKinlay for the
+   critical test case.
+ - Integrated Tatsuya Bizenn's NETBSD threads support, with some
+   minimally tested changes.
+ - Added GC_strdup and friends to make leak detection work correctly
+   for strdup clients.  (Thanks to Jon Moore.)  Fixed the existing strdup
+   with malloc redirection to handle a null malloc return correctly.
+ - Fix Makefile.am, so it handles exe extensions under Cygwin correctly
+   for gctest.
+
 To do:
  - The USE_MUNMAP code should really use a separate data structure
    indexed by physical page to keep track of time since last use of
index 1716514bec164376f768bcedb4889f54e74f8758..ed16950e2f0b342676eb3cc0f670794bb022378f 100644 (file)
@@ -34,6 +34,12 @@ after defining the appropriate <TT>GC_</tt><I>XXXX</i><TT>_THREADS</tt> macro.
 The header file <TT>gc.h</tt> must be included
 in files that use either GC or threads primitives, since threads primitives
 will be redefined to cooperate with the GC on many platforms.
+<P>
+Thread users should also be aware that on many platforms objects reachable
+only from thread-local variables may be prematurely reclaimed.
+Thus objects pointed to by thread-local variables should also be pointed to
+by a globally visible data structure.  (This is viewed as a bug, but as
+one that is exceedingly hard to fix without some libc hooks.)
 <DL>
 <DT> <B>void * GC_MALLOC(size_t <I>nbytes</i>)</b>
 <DD>
@@ -180,6 +186,11 @@ but are scanned for pointers to collectable objects.
 They are allocated by <TT>GC_MALLOC_UNCOLLECTABLE</tt>, as described
 above, and through some interfaces described below.
 <P>
+(On most platforms, the collector may not trace correctly from in-flight
+exception objects.  Thus objects thrown as exceptions should only
+point to otherwise reachable memory.  This is another bug whose
+proper repair requires platform hooks.)
+<P>
 The easiest way to ensure that collectable objects are properly referenced
 is to allocate only collectable objects.  This requires that every
 allocation go through one of the following interfaces, each one of
index 749bf824681a7d14831a8cb5a9b44c226614b158..c910609af775172669c32a1417da9e0ae1717356 100644 (file)
@@ -776,8 +776,8 @@ void GC_register_dynamic_libraries()
   /* this automatically, and rely largely on user input.       */
   /* We expect that any mapping with type MEM_MAPPED (which    */
   /* apparently excludes library data sections) can be safely  */
-  /* ignored.  But we're too chicken to do that in this        */
-  /* version.                                                  */
+  /* ignored.  But we're too completely remove this code in    */
+  /* this version.                                             */
   /* Based on a very limited sample, it appears that:          */
   /*   - Frame buffer mappings appear as mappings of large     */
   /*     length, usually a bit less than a power of two.       */
@@ -844,6 +844,9 @@ void GC_register_dynamic_libraries()
   }
 # endif /* DEBUG_VIRTUALQUERY */
 
+  extern GC_bool GC_wnt;  /* Is Windows NT derivative.         */
+                         /* Defined and set in os_dep.c.       */
+
   void GC_register_dynamic_libraries()
   {
     MEMORY_BASIC_INFORMATION buf;
@@ -885,7 +888,12 @@ void GC_register_dynamic_libraries()
                 * !is_frame_buffer(p, buf.RegionSize, buf.Type)
                 * instead of just checking for MEM_IMAGE.
                 * If something breaks, change it back. */
-               && buf.Type == MEM_IMAGE) {  
+               /* There is some evidence that we cannot always
+                * ignore MEM_PRIVATE sections under Windows ME
+                * and predecessors.  Hence we now also check for
+                * that case.   */
+               && (buf.Type == MEM_IMAGE ||
+                   !GC_wnt && buf.Type == MEM_PRIVATE)) {  
 #              ifdef DEBUG_VIRTUALQUERY
                  GC_dump_meminfo(&buf);
 #              endif
index b7be1d84930be9fb4d54fd59b70572815deb8eda..90c588499530b53e5f3d4aafc272de27e78c919c 100644 (file)
--- a/headers.c
+++ b/headers.c
@@ -210,7 +210,7 @@ register struct hblk * h;
     result = alloc_hdr();
     SET_HDR(h, result);
 #   ifdef USE_MUNMAP
-       result -> hb_last_reclaimed = GC_gc_no;
+       result -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #   endif
     return(result);
 }
index 3d4de46706a71d9f66f23a533744ee9bd7446928..e1bbdebb89c0e6370659b8b588a75b6bbc19ae6c 100644 (file)
@@ -129,7 +129,7 @@ GC_API int GC_java_finalization;
                        /* ordered finalization.  Default value is      */
                        /* determined by JAVA_FINALIZATION macro.       */
 
-GC_API void (* GC_finalizer_notifier)();
+GC_API void (* GC_finalizer_notifier) GC_PROTO((void));
                        /* Invoked by the collector when there are      */
                        /* objects to be finalized.  Invoked at most    */
                        /* once per GC cycle.  Never invoked unless     */
@@ -267,6 +267,7 @@ GC_API void GC_init GC_PROTO((void));
  */
 GC_API GC_PTR GC_malloc GC_PROTO((size_t size_in_bytes));
 GC_API GC_PTR GC_malloc_atomic GC_PROTO((size_t size_in_bytes));
+GC_API char *GC_strdup GC_PROTO((const char *str));
 GC_API GC_PTR GC_malloc_uncollectable GC_PROTO((size_t size_in_bytes));
 GC_API GC_PTR GC_malloc_stubborn GC_PROTO((size_t size_in_bytes));
 
@@ -523,6 +524,8 @@ GC_API GC_PTR GC_debug_malloc
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_atomic
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
+GC_API char *GC_debug_strdup
+       GC_PROTO((const char *str, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_uncollectable
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_stubborn
@@ -557,6 +560,7 @@ GC_API GC_PTR GC_debug_realloc_replacement
 # ifdef GC_DEBUG
 #   define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS)
 #   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
+#   define GC_STRDUP(s) GC_debug_strdup((s), GC_EXTRAS)
 #   define GC_MALLOC_UNCOLLECTABLE(sz) \
                        GC_debug_malloc_uncollectable(sz, GC_EXTRAS)
 #   define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
@@ -580,6 +584,7 @@ GC_API GC_PTR GC_debug_realloc_replacement
 # else
 #   define GC_MALLOC(sz) GC_malloc(sz)
 #   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
+#   define GC_STRDUP(s) GC_strdup(s)
 #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
 #   define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
                        GC_malloc_ignore_off_page(sz)
@@ -889,7 +894,7 @@ GC_API void (*GC_is_visible_print_proc)
 GC_PTR GC_malloc_many(size_t lb);
 #define GC_NEXT(p) (*(GC_PTR *)(p))    /* Retrieve the next element    */
                                        /* in returned list.            */
-extern void GC_thr_init();     /* Needed for Solaris/X86       */
+extern void GC_thr_init GC_PROTO((void));/* Needed for Solaris/X86     */
 
 #endif /* THREADS && !SRC_M3 */
 
@@ -940,8 +945,16 @@ extern void GC_thr_init(); /* Needed for Solaris/X86       */
      * from the statically loaded program section.
      * This circumvents a Solaris 2.X (X<=4) linker bug.
      */
-#   define GC_INIT() { extern end, etext; \
-                      GC_noop(&end, &etext); }
+#   ifdef __cplusplus
+#     define GC_INIT() { extern int _end[], _etext[]; \
+                        extern "C" void GC_noop1(GC_word); \
+                        GC_noop1((GC_word)_end); \
+                        GC_noop1((GC_word)_etext); }
+#   else
+#     define GC_INIT() { extern int _end[], _etext[]; \
+                        extern void GC_noop(); \
+                        GC_noop(_end, _etext); }
+#   endif /* !__cplusplus */
 #else
 # if defined(__CYGWIN32__) || defined (_AIX)
     /*
index 4671864b89bc56a31e1cd6aeb5bb445c6d98995b..8e3a8ae2ae9ec715164514d2ed85303405d06db8 100644 (file)
                             || defined(GC_SOLARIS_PTHREADS) \
                             || defined(GC_HPUX_THREADS) \
                             || defined(GC_AIX_THREADS) \
-                            || defined(GC_LINUX_THREADS))
+                            || defined(GC_LINUX_THREADS) \
+                            || defined(GC_NETBSD_THREADS))
 # define _REENTRANT
        /* Better late than never.  This fails if system headers that   */
        /* depend on this were previously included.                     */
 #endif
 
+#if !defined(_PTHREADS) && defined(GC_NETBSD_THREADS)
+# define _PTHREADS
+#endif
+
 #if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
 # define _POSIX4A_DRAFT10_SOURCE 1
 #endif
@@ -56,7 +61,7 @@
        defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
        defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
        defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \
-       defined(GC_AIX_THREADS) || \
+        defined(GC_AIX_THREADS) || defined(GC_NETBSD_THREADS) || \
         (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
 #   define GC_PTHREADS
 # endif
@@ -66,7 +71,7 @@
 #   define GC_LINUX_THREADS
 #   define GC_PTHREADS
 # endif
-# if !defined(LINUX) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
+# if !defined(__linux__) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
                          || defined(hppa) || defined(__HPPA))
 #   define GC_HPUX_THREADS
 #   define GC_PTHREADS
 #   define GC_FREEBSD_THREADS
 #   define GC_PTHREADS
 # endif
+# if !defined(GC_PTHREADS) && defined(__NetBSD__)
+#   define GC_NETBSD_THREADS
+#   define GC_PTHREADS
+# endif
 # if defined(DGUX) && (defined(i386) || defined(__i386__))
 #   define GC_DGUX386_THREADS
 #   define GC_PTHREADS
index 4f56f0d965fcf360112686fb0cdfb86fe315a468..da2fac025ae86c79d32c5d551c1a08006cf842e4 100644 (file)
@@ -180,7 +180,7 @@ class gc {public:
     inline void* operator new[]( size_t size, void *p );
     inline void operator delete[]( void* obj );
 #   ifdef GC_PLACEMENT_DELETE
-      inline void gc::operator delete[]( void*, void* );
+      inline void operator delete[]( void*, void* );
 #   endif
 #endif /* GC_OPERATOR_NEW_ARRAY */
     };    
index 842518cfcc48c2a0657b1cc6581994abf5cd8a44..21e9c9fa605fc15e4f3c29ce7a21861c226aa7fd 100644 (file)
@@ -73,6 +73,9 @@
 # define pthread_detach GC_pthread_detach
 
 #ifndef GC_DARWIN_THREADS
+# ifdef pthread_sigmask
+#  undef pthread_sigmask
+# endif         /* pthread_sigmask */
 # define pthread_sigmask GC_pthread_sigmask
 # define dlopen GC_dlopen
 #endif
index 0674ab4d09f6d1db7bc625b058145186cee75df6..1d02f400761f3b9920821c58786efa442d294a9f 100644 (file)
@@ -4,4 +4,6 @@
 #define calloc(m,n) GC_MALLOC((m)*(n))
 #define free(p) GC_FREE(p)
 #define realloc(p,n) GC_REALLOC((p),(n))
+#undef strdup
+#define strdup(s) GC_STRDUP((s))
 #define CHECK_LEAKS() GC_gcollect()
index c9539c188af36284316b60247f5b8b04a12bc2ed..c1565b28ff34c19e46d7eb622db59cf2b293defb 100644 (file)
 #      define GC_TEST_AND_SET_DEFINED
 #    endif
 #    if defined(POWERPC)
-#     if CPP_WORDSZ == 64
-        inline static int GC_test_and_set(volatile unsigned int *addr) {
-          unsigned long oldval;
-          unsigned long temp = 1; /* locked value */
-
-          __asm__ __volatile__(
-               "1:\tldarx %0,0,%3\n"   /* load and reserve               */
-               "\tcmpdi %0, 0\n"       /* if load is                     */
-               "\tbne 2f\n"            /*   non-zero, return already set */
-               "\tstdcx. %2,0,%1\n"    /* else store conditional         */
-               "\tbne- 1b\n"           /* retry if lost reservation      */
-               "\tsync\n"              /* import barrier                 */
-               "2:\t\n"                /* oldval is zero if we set       */
-              : "=&r"(oldval), "=p"(addr)
-              : "r"(temp), "1"(addr)
-              : "cr0","memory");
-          return (int)oldval;
-        }
-#     else
         inline static int GC_test_and_set(volatile unsigned int *addr) {
           int oldval;
           int temp = 1; /* locked value */
               : "cr0","memory");
           return oldval;
         }
-#     endif
 #     define GC_TEST_AND_SET_DEFINED
       inline static void GC_clear(volatile unsigned int *addr) {
        __asm__ __volatile__("lwsync" : : : "memory");
 #    ifdef ARM32
         inline static int GC_test_and_set(volatile unsigned int *addr) {
           int oldval;
-          /* SWP on ARM is very similar to XCHG on x86.  Doesn't lock the
-           * bus because there are no SMP ARM machines.  If/when there are,
-           * this code will likely need to be updated. */
-          /* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */
-          __asm__ __volatile__("swp %0, %1, [%2]"
-                            : "=r"(oldval)
-                            : "r"(1), "r"(addr)
-                            : "memory");
+          /* SWP on ARM is very similar to XCHG on x86.                */
+         /* The first operand is the result, the second the value      */
+         /* to be stored.  Both registers must be different from addr. */
+         /* Make the address operand an early clobber output so it     */
+         /* doesn't overlap with the other operands.  The early clobber*/
+         /* on oldval is neccessary to prevent the compiler allocating */
+         /* them to the same register if they are both unused.         */
+          __asm__ __volatile__("swp %0, %2, [%3]"
+                             : "=&r"(oldval), "=&r"(addr)
+                             : "r"(1), "1"(addr)
+                             : "memory");
           return oldval;
         }
 #       define GC_TEST_AND_SET_DEFINED
index 51981914dc5fcf71e5fa54680fdadc33c9390392..714fc428ee8aa32d160df816297dd67cb88922ff 100644 (file)
@@ -248,7 +248,8 @@ exit_label: ; \
        if (map_entry == OFFSET_TOO_BIG) { \
          map_entry = displ % (hhdr -> hb_sz); \
          displ -= map_entry; \
-         if (displ + (hhdr -> hb_sz) > BYTES_TO_WORDS(HBLKSIZE)) { \
+         if (displ + (hhdr -> hb_sz) > BYTES_TO_WORDS(HBLKSIZE) \
+             && displ != 0) { \
            GC_ADD_TO_BLACK_LIST_NORMAL((word)current, source); \
            goto exit_label; \
          } \
index 3d634ceebfdf2d2455e5cb43e7325edb02725e77..2abd27dd7054268d9b5a61adc6bf944fbb3bae9c 100644 (file)
@@ -755,17 +755,9 @@ struct hblk {
 # ifdef LARGE_CONFIG
 #   define MAX_ROOT_SETS 4096
 # else
-#   ifdef PCR
-#     define MAX_ROOT_SETS 1024
-#   else
-#     if defined(MSWIN32) || defined(MSWINCE)
-#      define MAX_ROOT_SETS 1024
-           /* Under NT, we add only written pages, which can result    */
-           /* in many small root sets.                                 */
-#     else
-#       define MAX_ROOT_SETS 256
-#     endif
-#   endif
+    /* GCJ LOCAL: MAX_ROOT_SETS increased to permit more shared */
+    /* libraries to be loaded.                                  */ 
+#   define MAX_ROOT_SETS 1024
 # endif
 
 # define MAX_EXCLUSIONS (MAX_ROOT_SETS/4)
index c028e5dbf6cff8d028cce52f7de8a2dab00e19bf..ccba470ece963ab58ea1c1534ed7396dec35d904 100644 (file)
 #   if defined(__ppc__)  || defined(__ppc64__)
 #    define POWERPC
 #    define mach_type_known
-#   elif defined(__i386__)
+#   endif
+#   if defined(__i386__)
 #    define I386
-     --> Not really supported, but at least we recognize it.
+#    define mach_type_known
 #   endif
 # endif
 # if defined(NeXT) && defined(mc68000)
 #     define  mach_type_known
 #    endif 
 # endif
+# if defined(__TANDEM)
+    /* Nonstop S-series */
+    /* FIXME: Should recognize Integrity series? */
+#   define MIPS
+#   define NONSTOP
+#   define mach_type_known
+# endif
 
 /* Feel free to add more clauses here */
 
                    /*               FREEBSD, THREE86BSD, MSWIN32,      */
                    /*               BSDI,SUNOS5, NEXT, other variants) */
                     /*             NS32K      ==> Encore Multimax      */
-                    /*             MIPS       ==> R2000 or R3000       */
-                    /*                 (RISCOS, ULTRIX variants)       */
+                   /*             MIPS       ==> R2000 through R14K    */
+                    /*                 (many variants)                 */
                     /*            VAX        ==> DEC VAX               */
                     /*                 (BSD, ULTRIX variants)          */
                     /*            RS6000     ==> IBM RS/6000 AIX3.X    */
 /* #     define MPROTECT_VDB  Not quite working yet? */
 #     define DYNAMIC_LOADING
 #   endif
+#   ifdef DARWIN
+#     define OS_TYPE "DARWIN"
+#     define DARWIN_DONT_PARSE_STACK
+#     define DYNAMIC_LOADING
+      /* XXX: see get_end(3), get_etext() and get_end() should not be used.
+        These aren't used when dyld support is enabled (it is by default) */
+#     define DATASTART ((ptr_t) get_etext())
+#     define DATAEND   ((ptr_t) get_end())
+#     define STACKBOTTOM ((ptr_t) 0xc0000000)
+#     define USE_MMAP
+#     define USE_MMAP_ANON
+#     define USE_ASM_PUSH_REGS
+      /* This is potentially buggy. It needs more testing. See the comments in
+        os_dep.c.  It relies on threads to track writes. */
+#     ifdef GC_DARWIN_THREADS
+/* #       define MPROTECT_VDB -- disabled for now.  May work for some apps. */
+#     endif
+#     include <unistd.h>
+#     define GETPAGESIZE() getpagesize()
+      /* There seems to be some issues with trylock hanging on darwin. This
+         should be looked into some more */
+#      define NO_PTHREAD_TRYLOCK
+#   endif /* DARWIN */
 # endif
 
 # ifdef NS32K
 #       define DATAEND /* not needed */
 #   endif
 #   if defined(NETBSD)
-#     define ALIGNMENT 4
 #     define OS_TYPE "NETBSD"
+#     define ALIGNMENT 4
 #     define HEURISTIC2
 #     define USE_GENERIC_PUSH_REGS
 #     ifdef __ELF__
 #       define STACKBOTTOM ((ptr_t) 0x7ffff000)
 #     endif /* _ELF_ */
 #  endif
+#  if defined(NONSTOP)
+#    define CPP_WORDSZ 32
+#    define OS_TYPE "NONSTOP"
+#    define ALIGNMENT 4
+#    define DATASTART ((ptr_t) 0x08000000)
+     extern int _end[];
+#    define DATAEND (_end)
+#    define STACKBOTTOM ((ptr_t) 0x4fffffff)
+#    define USE_GENERIC_PUSH_REGS
+#   endif
 # endif
 
 # ifdef RS6000
 #      define OS_TYPE "NETBSD"
 #      define HEURISTIC2
 #      define DATASTART GC_data_start
-#       define USE_GENERIC_PUSH_REGS
+#      define USE_GENERIC_PUSH_REGS
 #      define DYNAMIC_LOADING
 #   endif
 # endif
 #   define SUNOS5SIGS
 # endif
 
+# ifdef GC_NETBSD_THREADS
+#   define SIGRTMIN 33
+#   define SIGRTMAX 63
+# endif
+
 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
            || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
            || defined(DGUX) || defined(BSD) || defined(SUNOS4) \
 # if defined(GC_LINUX_THREADS) && !defined(LINUX)
        --> inconsistent configuration
 # endif
+# if defined(GC_NETBSD_THREADS) && !defined(NETBSD)
+       --> inconsistent configuration
+# endif
 # if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5)
        --> inconsistent configuration
 # endif
                                            + GC_page_size) \
                                            + GC_page_size-1)
 #   else
-#     if defined(NEXT) || defined(DOS4GW) || \
+#     if defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) || \
                 (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
                 (defined(SUNOS5) && !defined(USE_MMAP))
 #       define GET_MEM(bytes) HBLKPTR((size_t) \
index cb3f37663861a634d0bf100c0f15a4831b0d21f3..b7617df1d905a42c8b672a6a1e37e5e15b4f60ca 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -15,6 +15,8 @@
 /* Boehm, February 7, 1996 4:32 pm PST */
  
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
 #include "private/gc_priv.h"
 
 extern ptr_t GC_clear_stack(); /* in misc.c, behaves like identity */
@@ -271,6 +273,26 @@ DCL_LOCK_STATE;
    }
 }
 
+/* provide a version of strdup() that uses the collector to allocate the
+   copy of the string */
+# ifdef __STDC__
+    char *GC_strdup(const char *s)
+# else
+    char *GC_strdup(s)
+    char *s;
+#endif
+{
+  char *copy;
+
+  if (s == NULL) return NULL;
+  if ((copy = GC_malloc_atomic(strlen(s) + 1)) == NULL) {
+    errno = ENOMEM;
+    return NULL;
+  }
+  strcpy(copy, s);
+  return copy;
+}
+
 /* Allocate lb bytes of composite (pointerful) data */
 # ifdef __STDC__
     GC_PTR GC_malloc(size_t lb)
@@ -370,6 +392,10 @@ DCL_LOCK_STATE;
   {
     size_t len = strlen(s) + 1;
     char * result = ((char *)REDIRECT_MALLOC(len+1));
+    if (result == 0) {
+      errno = ENOMEM;
+      return 0;
+    }
     BCOPY(s, result, len+1);
     return result;
   }
diff --git a/mark.c b/mark.c
index 09dfe92af3152d01289982c667a6ee6d14ed5759..c56fb4d569701984353b6b1adc2e372e22120d0d 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -1486,7 +1486,6 @@ ptr_t top;
 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   */
     /* saved inside GC frames are marked before they disappear.                */
     /* The rest of the marking can be deferred until later.            */
diff --git a/misc.c b/misc.c
index 52567b7ded873b3da113415e6a9b6cb1d735b220..3cd15667920733a0dd086191505cc2b6261bf3ee 100644 (file)
--- a/misc.c
+++ b/misc.c
 # include <tchar.h>
 #endif
 
+#ifdef NONSTOP
+# include <floss.h>
+#endif
+
 # ifdef THREADS
 #   ifdef PCR
 #     include "il/PCR_IL.h"
@@ -477,10 +481,11 @@ void GC_init()
 #if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
     if (!GC_is_initialized) {
       BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL;
-      HMODULE hK32 = GetModuleHandle("kernel32.dll");
+      HMODULE hK32 = GetModuleHandleA("kernel32.dll");
       if (hK32)
-          (FARPROC) pfn = GetProcAddress(hK32,
-                         "InitializeCriticalSectionAndSpinCount");
+         pfn = (BOOL (WINAPI *) (LPCRITICAL_SECTION, DWORD))
+               GetProcAddress (hK32,
+                               "InitializeCriticalSectionAndSpinCount");
       if (pfn)
           pfn(&GC_allocate_ml, 4000);
       else
index fb50a4554b778e9168e3a8fd6ee54da81e88229e..b6068c9c9a508f967d54a71d6a1edb9e0d81c07d 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -1181,12 +1181,15 @@ void GC_register_data_segments()
        /* This used to be set for gcc, to avoid dealing with           */
        /* the structured exception handling issues.  But we now have   */
        /* assembly code to do that right.                              */
+  GC_bool GC_wnt = FALSE;
+        /* This is a Windows NT derivative, i.e. NT, W2K, XP or later.  */
   
   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);
+    GC_wnt = !(v & 0x80000000);
+    GC_no_win32_dlls |= ((!GC_wnt) && (v & 0xff) <= 3);
   }
 
   /* Return the smallest address a such that VirtualQuery              */
@@ -1498,7 +1501,7 @@ void GC_register_data_segments()
 
 # if !defined(OS2) && !defined(PCR) && !defined(AMIGA) \
        && !defined(MSWIN32) && !defined(MSWINCE) \
-       && !defined(MACOS) && !defined(DOS4GW)
+       && !defined(MACOS) && !defined(DOS4GW) && !defined(NONSTOP)
 
 # ifdef SUNOS4
     extern caddr_t sbrk();
@@ -3799,8 +3802,12 @@ catch_exception_raise(
         mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT;
         ppc_exception_state64_t exc_state;
 #     endif
+#   elif defined(I386)
+        thread_state_flavor_t flavor = i386_EXCEPTION_STATE;
+        mach_msg_type_number_t exc_state_count = i386_EXCEPTION_STATE_COUNT;
+        i386_exception_state_t exc_state;
 #   else
-#      error FIXME for non-ppc darwin
+#      error FIXME for non-ppc/x86 darwin
 #   endif
 
     
@@ -3830,7 +3837,13 @@ catch_exception_raise(
     }
     
     /* This is the address that caused the fault */
+#if defined(POWERPC)
     addr = (char*) exc_state.dar;
+#elif defined (I386)
+    addr = (char*) exc_state.faultvaddr;
+#else
+#   error FIXME for non POWERPC/I386
+#endif
         
     if((HDR(addr)) == 0) {
         /* Ugh... just like the SIGBUS problem above, it seems we get a bogus 
index fd23110b80b511db8d95e32e6629587b7e62907b..1121ee89c6e4661853a500fd1484f2684f594059 100644 (file)
@@ -1,10 +1,21 @@
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define lgu     MODE_CHOICE(lwzu, ldu)
+
+#define g_long  MODE_CHOICE(long, quad)         /* usage is ".g_long" */
+
+#define LOG2_GPR_BYTES  MODE_CHOICE(2,3)        /* log2(GPR_BYTES) */
 
 ; GC_push_regs function. Under some optimization levels GCC will clobber
 ; some of the non-volatile registers before we get a chance to save them
 ; therefore, this cannot be inline asm.
 
 .text
-       .align 2
+       .align LOG2_GPR_BYTES
        .globl _GC_push_regs
 _GC_push_regs:
     
@@ -65,7 +76,7 @@ _GC_push_regs:
 
 .data
 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
-       .align 2
+       .align LOG2_GPR_BYTES
 L_GC_push_one$stub:
        .indirect_symbol _GC_push_one
        mflr r0
@@ -74,12 +85,11 @@ L0$_GC_push_one:
        mflr r11
        addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
        mtlr r0
-       lwzu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
+       lgu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
        mtctr r12
        bctr
 .data
 .lazy_symbol_pointer
 L_GC_push_one$lazy_ptr:
        .indirect_symbol _GC_push_one
-       .long dyld_stub_binding_helper
-
+       .g_long dyld_stub_binding_helper
index b9034dc7f5bfb0c5ff626f4cf65f160c74129c0d..66d7b5c0c96289fbf8cb6f86be4ceb5b5ae90fd0 100644 (file)
@@ -107,7 +107,7 @@ void GC_brief_async_signal_safe_sleep()
  */
 
 #ifndef SIG_THR_RESTART
-#  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+#  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || defined(GC_NETBSD_THREADS)
 #    ifdef _SIGRTMIN
 #      define SIG_THR_RESTART _SIGRTMIN + 5
 #    else
@@ -120,6 +120,13 @@ void GC_brief_async_signal_safe_sleep()
 
 sem_t GC_suspend_ack_sem;
 
+#ifdef GC_NETBSD_THREADS
+# define GC_NETBSD_THREADS_WORKAROUND
+  /* It seems to be necessary to wait until threads have restarted.    */
+  /* But it is unclear why that is the case.                           */
+  sem_t GC_restart_ack_sem;
+#endif
+
 void GC_suspend_handler_inner(ptr_t sig_arg);
 
 #if defined(IA64) || defined(HP_PA)
@@ -227,6 +234,10 @@ void GC_restart_handler(int sig)
 
     if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
 
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    sem_post(&GC_restart_ack_sem);
+#endif
+
     /*
     ** Note: even if we don't do anything useful here,
     ** it would still be necessary to have a signal handler,
@@ -303,6 +314,8 @@ void GC_push_all_stacks()
                (unsigned long) bs_lo, (unsigned long) bs_hi);
 #        endif
           if (pthread_equal(p -> id, me)) {
+           /* FIXME:  This may add an unbounded number of entries,     */
+           /* and hence overflow the mark stack, which is bad.         */
            GC_push_all_eager(bs_lo, bs_hi);
          } else {
            GC_push_all_stack(bs_lo, bs_hi);
@@ -439,6 +452,9 @@ void GC_start_world()
     register GC_thread p;
     register int n_live_threads = 0;
     register int result;
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    int code;
+#endif
 
 #   if DEBUG_THREADS
       GC_printf0("World starting\n");
@@ -468,6 +484,14 @@ void GC_start_world()
         }
       }
     }
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    for (i = 0; i < n_live_threads; i++)
+       while (0 != (code = sem_wait(&GC_restart_ack_sem)))
+           if (errno != EINTR) {
+               GC_err_printf1("sem_wait() returned %ld\n", (unsigned long)code);
+               ABORT("sem_wait() for restart handler failed");
+           }
+#endif
     #if DEBUG_THREADS
       GC_printf0("World started\n");
     #endif
@@ -478,6 +502,10 @@ void GC_stop_init() {
     
     if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
         ABORT("sem_init failed");
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    if (sem_init(&GC_restart_ack_sem, 0, 0) != 0)
+       ABORT("sem_init failed");
+#endif
 
     act.sa_flags = SA_RESTART;
     if (sigfillset(&act.sa_mask) != 0) {
index 5b3808e7689a3aa26dc5001c345cd9b80ad4c305..e8f49027e15d09800595fde2e5b14d24a26ff583 100644 (file)
@@ -67,7 +67,8 @@
 # endif
 
 # if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
-      defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) \
+      defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) || \
+      defined(GC_NETBSD_THREADS))                             \
       && !defined(USE_PTHREAD_SPECIFIC)
 #   define USE_PTHREAD_SPECIFIC
 # endif
 # include <sys/sysctl.h>
 #endif /* GC_DARWIN_THREADS */
 
-
+#if defined(GC_NETBSD_THREADS)
+# include <sys/param.h>
+# include <sys/sysctl.h>
+#endif /* GC_NETBSD_THREADS */
 
 #if defined(GC_DGUX386_THREADS)
 # include <sys/dg_sys_info.h>
@@ -836,6 +840,18 @@ int GC_get_nprocs()
 }
 #endif /* GC_DGUX386_THREADS */
 
+#if defined(GC_NETBSD_THREADS)
+static int get_ncpu(void)
+{
+    int mib[] = {CTL_HW,HW_NCPU};
+    int res;
+    size_t len = sizeof(res);
+
+    sysctl(mib, sizeof(mib)/sizeof(int), &res, &len, NULL, 0);
+    return res;
+}
+#endif /* GC_NETBSD_THREADS */
+
 /* We hold the allocation lock.        */
 void GC_thr_init()
 {
@@ -881,6 +897,9 @@ void GC_thr_init()
          GC_nprocs = sysconf(_SC_NPROC_ONLN);
          if (GC_nprocs <= 0) GC_nprocs = 1;
 #       endif
+#       if defined(GC_NETBSD_THREADS)
+         GC_nprocs = get_ncpu();
+#       endif
 #       if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS)
          int ncpus = 1;
          size_t len = sizeof(ncpus);
index 9078c8d8cd99f4e7bcf71a3d4990375a9ab9e9fd..6999fb81cb4ec2fa9ede5c5c4a78d98ac789af12 100644 (file)
@@ -22,6 +22,10 @@ int main()
           printf("-pthread\n");
 #       endif
 #   endif
+#   if defined(GC_NETBSD_THREADS)
+         printf("-lpthread -lrt\n");
+#   endif
+
 #   if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
        printf("-lpthread -lrt\n");
 #   endif
index e1fe24bd0abe84e8b3f15b950721c724ec612f20..930f3f27d86c357b3be91133d45ee7b955b83beb 100644 (file)
--- a/version.h
+++ b/version.h
@@ -2,7 +2,7 @@
 /* Eventually this one may become unnecessary.  For now we need        */
 /* it to keep the old-style build process working.             */
 #define GC_TMP_VERSION_MAJOR 6
-#define GC_TMP_VERSION_MINOR 6
+#define GC_TMP_VERSION_MINOR 7
 #define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA
 
 #ifndef GC_NOT_ALPHA