diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2014-05-17 18:30:04 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2014-05-17 18:30:04 +0400 |
commit | 33f4163606ab76cdd611b16a290daccb3bb9a41b (patch) | |
tree | c22825cb48bbafbb34e67ef1900280e4d1d7aded | |
parent | 933242d70c94a44016749310ea2ea647b1ef24e0 (diff) | |
parent | 9f27ae7aee7a12b3c99d0ce7dc4c7384e3189fa2 (diff) |
Merge tag 'gc6_0' into ancient-releases
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | Makefile.direct | 13 | ||||
-rw-r--r-- | Makefile.dj | 7 | ||||
-rw-r--r-- | alpha_mach_dep.s | 109 | ||||
-rwxr-xr-x | configure | 20 | ||||
-rw-r--r-- | configure.in | 8 | ||||
-rw-r--r-- | dbg_mlc.c | 2 | ||||
-rw-r--r-- | doc/README | 2 | ||||
-rw-r--r-- | doc/README.changes | 32 | ||||
-rw-r--r-- | doc/README.macros | 78 | ||||
-rw-r--r-- | dyn_load.c | 4 | ||||
-rw-r--r-- | finalize.c | 66 | ||||
-rw-r--r-- | include/gc.h | 10 | ||||
-rw-r--r-- | include/gc_cpp.h | 33 | ||||
-rw-r--r-- | include/private/dbg_mlc.h | 5 | ||||
-rw-r--r-- | include/private/gc_priv.h | 2 | ||||
-rw-r--r-- | include/private/gcconfig.h | 38 | ||||
-rw-r--r-- | linux_threads.c | 33 | ||||
-rw-r--r-- | mach_dep.c | 57 | ||||
-rw-r--r-- | misc.c | 6 | ||||
-rw-r--r-- | os_dep.c | 95 | ||||
-rwxr-xr-x | powerpc_macosx_mach_dep.s | 6 | ||||
-rw-r--r-- | version.h | 2 |
23 files changed, 440 insertions, 201 deletions
@@ -1,4 +1,4 @@ -# This is the original manually generated Makefile. It may stil be used +# This is the original manually generated Makefile. It may still be used # to build the collector. # # Primary targets: @@ -88,10 +88,11 @@ HOSTCFLAGS=$(CFLAGS) # code from the heap. Currently this only affects the incremental # collector on UNIX machines. It may greatly improve its performance, # since this may avoid some expensive cache synchronization. -# -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the -# new syntax "operator new[]" for allocating and deleting arrays. +# -DGC_NO_OPERATOR_NEW_ARRAY declares that the C++ compiler does not support +# the new syntax "operator new[]" for allocating and deleting arrays. # See gc_cpp.h for details. No effect on the C part of the collector. -# This is defined implicitly in a few environments. +# This is defined implicitly in a few environments. Must also be defined +# by clients that use gc_cpp.h. # -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined # as aliases for X, GC_realloc, and GC_free, respectively. # Calloc is redefined in terms of the new malloc. X should @@ -250,7 +251,7 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ doc/README.win32 doc/barrett_diagram doc/README \ doc/README.contributors doc/README.changes doc/gc.man \ doc/README.environment doc/tree.html doc/gcdescr.html \ - doc/README.autoconf + doc/README.autoconf doc/README.macros TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \ tests/leak_test.c tests/thread_leak_test.c @@ -516,7 +517,7 @@ KandRtest: setjmp_test gctest ./setjmp_test ./gctest -add_gc_prefix: $(srcdir)/add_gc_prefix.c +add_gc_prefix: $(srcdir)/add_gc_prefix.c $(srcdir)/version.h $(CC) -o add_gc_prefix $(srcdir)/add_gc_prefix.c gcname: $(srcdir)/gcname.c $(srcdir)/version.h diff --git a/Makefile.direct b/Makefile.direct index e2df4529..a5d24c65 100644 --- a/Makefile.direct +++ b/Makefile.direct @@ -1,4 +1,4 @@ -# This is the original manually generated Makefile. It may stil be used +# This is the original manually generated Makefile. It may still be used # to build the collector. # # Primary targets: @@ -88,10 +88,11 @@ HOSTCFLAGS=$(CFLAGS) # code from the heap. Currently this only affects the incremental # collector on UNIX machines. It may greatly improve its performance, # since this may avoid some expensive cache synchronization. -# -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the -# new syntax "operator new[]" for allocating and deleting arrays. +# -DGC_NO_OPERATOR_NEW_ARRAY declares that the C++ compiler does not support +# the new syntax "operator new[]" for allocating and deleting arrays. # See gc_cpp.h for details. No effect on the C part of the collector. -# This is defined implicitly in a few environments. +# This is defined implicitly in a few environments. Must also be defined +# by clients that use gc_cpp.h. # -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined # as aliases for X, GC_realloc, and GC_free, respectively. # Calloc is redefined in terms of the new malloc. X should @@ -250,7 +251,7 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ doc/README.win32 doc/barrett_diagram doc/README \ doc/README.contributors doc/README.changes doc/gc.man \ doc/README.environment doc/tree.html doc/gcdescr.html \ - doc/README.autoconf + doc/README.autoconf doc/README.macros TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \ tests/leak_test.c tests/thread_leak_test.c @@ -516,7 +517,7 @@ KandRtest: setjmp_test gctest ./setjmp_test ./gctest -add_gc_prefix: $(srcdir)/add_gc_prefix.c +add_gc_prefix: $(srcdir)/add_gc_prefix.c $(srcdir)/version.h $(CC) -o add_gc_prefix $(srcdir)/add_gc_prefix.c gcname: $(srcdir)/gcname.c $(srcdir)/version.h diff --git a/Makefile.dj b/Makefile.dj index 26434492..09fae4e6 100644 --- a/Makefile.dj +++ b/Makefile.dj @@ -62,10 +62,11 @@ CFLAGS= -O -I$(srcdir)/include -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIO # code from the heap. Currently this only affects the incremental # collector on UNIX machines. It may greatly improve its performance, # since this may avoid some expensive cache synchronization. -# -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the -# new syntax "operator new[]" for allocating and deleting arrays. +# -DGC_NO_OPERATOR_NEW_ARRAY declares that the C++ compiler does not support +# the new syntax "operator new[]" for allocating and deleting arrays. # See gc_cpp.h for details. No effect on the C part of the collector. -# This is defined implicitly in a few environments. +# This is defined implicitly in a few environments. Must also be defined +# by clients that use gc_cpp.h. # -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined # as aliases for X, GC_realloc, and GC_free, respectively. # Calloc is redefined in terms of the new malloc. X should diff --git a/alpha_mach_dep.s b/alpha_mach_dep.s index 783ebf1f..53547307 100644 --- a/alpha_mach_dep.s +++ b/alpha_mach_dep.s @@ -1,64 +1,87 @@ # $Id: alpha_mach_dep.s,v 1.2 1993/01/18 22:54:51 dosser Exp $ + .arch ev6 -# This is BROKEN on a 21264 running gcc, and probably in other cases. -# The compiler may spill pointers to fp registers, and this code doesn't -# scan those. - -# define call_push(x) \ - lda $16, 0(x); /* copy x to first argument register */ \ - jsr $26, GC_push_one; /* call GC_push_one, ret addr in $26 */ \ - ldgp $gp, 0($26) /* restore $gp register from $ra */ - .text .align 4 .globl GC_push_regs .ent GC_push_regs 2 GC_push_regs: - ldgp $gp, 0($27) # set gp from the procedure value reg - lda $sp, -32($sp) # make stack frame - stq $26, 8($sp) # save return address - .mask 0x04000000, -8 + ldgp $gp, 0($27) + lda $sp, -16($sp) + stq $26, 0($sp) + .mask 0x04000000, 0 .frame $sp, 16, $26, 0 - # call_push($0) # expression eval and int func result - - # call_push($1) # temp regs - not preserved cross calls - # call_push($2) - # call_push($3) - # call_push($4) - # call_push($5) - # call_push($6) - # call_push($7) - # call_push($8) + # $0 integer result + # $1-$8 temp regs - not preserved cross calls + # $9-$15 call saved regs + # $16-$21 argument regs - not preserved cross calls + # $22-$28 temp regs - not preserved cross calls + # $29 global pointer - not preserved cross calls + # $30 stack pointer - call_push($9) # Saved regs +# define call_push(x) \ + mov x, $16; \ + jsr $26, GC_push_one; \ + ldgp $gp, 0($26) + + call_push($9) call_push($10) call_push($11) call_push($12) call_push($13) call_push($14) + call_push($15) + + # $f0-$f1 floating point results + # $f2-$f9 call saved regs + # $f10-$f30 temp regs - not preserved cross calls + + # Use the most efficient transfer method for this hardware. + # Bit 1 detects the FIX extension, which includes ftoit. + amask 2, $0 + bne $0, $use_stack + +#undef call_push +#define call_push(x) \ + ftoit x, $16; \ + jsr $26, GC_push_one; \ + ldgp $gp, 0($26) + + call_push($f2) + call_push($f3) + call_push($f4) + call_push($f5) + call_push($f6) + call_push($f7) + call_push($f8) + call_push($f9) + + ldq $26, 0($sp) + lda $sp, 16($sp) + ret $31, ($26), 1 - call_push($15) # frame ptr or saved reg + .align 4 +$use_stack: - # call_push($16) # argument regs - not preserved cross calls - # call_push($17) - # call_push($18) - # call_push($19) - # call_push($20) - # call_push($21) +#undef call_push +#define call_push(x) \ + stt x, 8($sp); \ + ldq $16, 8($sp); \ + jsr $26, GC_push_one; \ + ldgp $gp, 0($26) - # call_push($22) # temp regs - not preserved cross calls - # call_push($23) - # call_push($24) - # call_push($25) + call_push($f2) + call_push($f3) + call_push($f4) + call_push($f5) + call_push($f6) + call_push($f7) + call_push($f8) + call_push($f9) - # call_push($26) # return address - expression eval - # call_push($27) # procedure value or temporary reg - # call_push($28) # assembler temp - not presrved - call_push($29) # Global Pointer - # call_push($30) # Stack Pointer + ldq $26, 0($sp) + lda $sp, 16($sp) + ret $31, ($26), 1 - ldq $26, 8($sp) # restore return address - lda $sp, 32($sp) # pop stack frame - ret $31, ($26), 1 # return ($31 == hardwired zero) .end GC_push_regs @@ -2192,6 +2192,16 @@ EOF EOF ;; + *-*-linux*) + cat >> confdefs.h <<\EOF +#define GC_LINUX_THREADS 1 +EOF + + cat >> confdefs.h <<\EOF +#define _REENTRANT 1 +EOF + + ;; *-*-hpux*) echo "configure: warning: "Only HP/UX 11 threads are supported."" 1>&2 cat >> confdefs.h <<\EOF @@ -2214,16 +2224,6 @@ EOF THREADLIBS="-lpthread -lrt" ;; - *-*-linux*) - cat >> confdefs.h <<\EOF -#define GC_LINUX_THREADS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _REENTRANT 1 -EOF - - ;; *-*-freebsd*) echo "configure: warning: "FreeBSD does not yet fully support threads with Boehm GC."" 1>&2 cat >> confdefs.h <<\EOF diff --git a/configure.in b/configure.in index 0d8cf68a..fa3f81ac 100644 --- a/configure.in +++ b/configure.in @@ -80,6 +80,10 @@ case "$THREADS" in fi AC_DEFINE(THREAD_LOCAL_ALLOC) ;; + *-*-linux*) + AC_DEFINE(GC_LINUX_THREADS) + AC_DEFINE(_REENTRANT) + ;; *-*-hpux*) AC_MSG_WARN("Only HP/UX 11 threads are supported.") AC_DEFINE(GC_HPUX_THREADS) @@ -90,10 +94,6 @@ case "$THREADS" in AC_DEFINE(THREAD_LOCAL_ALLOC) THREADLIBS="-lpthread -lrt" ;; - *-*-linux*) - AC_DEFINE(GC_LINUX_THREADS) - AC_DEFINE(_REENTRANT) - ;; *-*-freebsd*) AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.") AC_DEFINE(FREEBSD_THREADS) @@ -273,7 +273,7 @@ word integer; /* But that's expensive. And this way things should only appear */ /* inconsistent while we're in the handler. */ # ifdef KEEP_BACK_PTRS - ((oh *)p) -> oh_back_ptr = 0; + ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); # endif ((oh *)p) -> oh_string = string; ((oh *)p) -> oh_int = integer; @@ -27,7 +27,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.0alpha8 of a conservative garbage collector for C and C++. +This is version 6.0 of a conservative garbage collector for C and C++. You might find a more recent version of this at diff --git a/doc/README.changes b/doc/README.changes index a058d359..c018c8b6 100644 --- a/doc/README.changes +++ b/doc/README.changes @@ -1349,9 +1349,41 @@ Since 6.0alpha7: (Thanks to Maarten Thibaut.) - Fixed up the GNU-style build files enough so that they work in some obvious cases. + - Added initial port to Digital Mars compiler for win32. (Thanks to Walter + Bright.) + +Since 6.0alpha8: + - added README.macros. + - Made gc.mak a symbolic link to work around winzip's tendency to ignore + hard links. + - Simplified the setting of NEED_FIND_LIMIT in os_dep.c, possibly breaking + it on untested platforms. + - Integrated initial GNU HURD port. (Thanks to Chris Lingard and Igor + Khavkine.) + - A few more fixes for Digital Mars compiler. + - Fixed gcc version recognition. Renamed OPERATOR_NEW_ARRAY to + GC_OPERATOR_NEW_ARRAY. Changed GC_OPERATOR_NEW_ARRAY to be the default. + It can be overridden with -DGC_NO_OPERATOR_NEW_ARRAY. (Thanks to + Cesar Eduardo Barros.) + - Changed the byte size to free-list mapping in thread local allocation + so that size 0 allocations are handled correctly. + - Fixed Linux/MIPS stackbottom for new toolchain. (Thanks to Ryan Murray.) + - Changed finalization registration to invoke GC_oom_fn when it runs out + of memory. + - Removed lvalue cast in finalize.c. This caused some debug configurations + not to build with some non-gcc compilers. + +Since 6.0alpha9: + - Two more bug fixes for KEEP_BACK_PTRS and DBG_HDRS_ALL. + - Fixed a stack clearing problem that resulted in SIGILL with a + misaligned stack pointer for multithreaded SPARC builds. + - Integrated another HURD patch (thanks to Igor Khavkine). To do: + - There seem to be outstanding issues on Solaris/X86, possibly with + finding the data segment starting address. Information/patches would + ne appreciated. - New_gc_alloc.h is apparently no longer compatible with the latest C++ standard library in gcc3.0. (This isn't technically a bug, since it only claimed compatibility with the SGI STL. But we may need a new C++ STL diff --git a/doc/README.macros b/doc/README.macros new file mode 100644 index 00000000..d9df8dd3 --- /dev/null +++ b/doc/README.macros @@ -0,0 +1,78 @@ +The collector uses a large amount of conditional compilation in order to +deal with platform dependencies. This violates a number of known coding +standards. On the other hand, it seems to be the only practical way to +support this many platforms without excessive code duplication. + +A few guidelines have mostly been followed in order to keep this manageable: + +1) #if and #ifdef directives are properly indented whenever easily possible. +All known C compilers allow whitespace between the "#" and the "if" to make +this possible. ANSI C also allows white space before the "#", though we +avoid that. It has the known disadvantages that it differs from the normal +GNU conventions, and that it makes patches larger than otherwise necessary. +In my opinion, it's still well worth it, for the same reason that we indent +ordinary "if" statements. + +2) Whenever possible, tests are performed on the macros defined in gcconfig.h +instead of directly testing patform-specific predefined macros. This makes it +relatively easy to adapt to new compilers with a different set of predefined +macros. Currently these macros generally identify platforms instead of +features. In many cases, this is a mistake. + +3) The code currently avoids #elif, eventhough that would make it more +readable. This was done since #elif would need to be understood by ALL +compilers used to build the collector, and that hasn't always been the case. +It makes sense to reconsider this decision at some point, since #elif has been +standardized at least since 1989. + +Many of the tested configuration macros are at least somewhat defined in +either include/private/gcconfig.h or in Makefile.direct. Here is an attempt +at defining some of the remainder: (Thanks to Walter Bright for suggesting +this. This is a work in progress) + +MACRO EXPLANATION +----- ----------- + +__DMC__ Always #define'd by the Digital Mars compiler. Expands + to the compiler version number in hex, i.e. 0x810 is + version 8.1b0 + +_ENABLE_ARRAYNEW + #define'd by the Digital Mars C++ compiler when + operator new[] and delete[] are separately + overloadable. Used in gc_cpp.h. + +_MSC_VER Expands to the Visual C++ compiler version. Assumed to + not be defined for other compilers (at least if they behave + appreciably differently). + +_DLL Defined by Visual C++ if dynamic libraries are being built + or used. Used to test whether __declspec(dllimport) or + __declspec(dllexport) needs to be added to declarations + to support the case in which the collector is in a dll. + +GC_DLL User-settable macro that forces the effect of _DLL. + +GC_NOT_DLL User-settable macro that overrides _DLL, e.g. if dynamic + libraries are used, but the collector is in a static library. + +__STDC__ Assumed to be defined only by compilers that understand + prototypes and other C89 features. Its value is generally + not used, since we are fine with most nonconforming extensions. + +SUNOS5SIGS Solaris-like signal handling. This is probably misnamed, + since it really doesn't guarantee much more than Posix. + Currently set only for Solaris2.X, HPUX, and DRSNX. Should + probably be set for some other platforms. + +PCR Set if the collector is being built as part of the Xerox + Portable Common Runtime. + +SRC_M3 Set if the collector is being built as a replacement of the + one in the DEC/Compaq SRC Modula-3 runtime. I suspect this + was last used around 1994, and no doubt broke a long time ago. + It's there primarily incase someone wants to port to a similar + system. + + + @@ -53,7 +53,7 @@ !(defined(ALPHA) && defined(OSF1)) && \ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \ !defined(RS6000) && !defined(SCO_ELF) && \ - !(defined(NETBSD) && defined(__ELF__)) + !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) --> We only know how to find data segments of dynamic libraries for the --> above. Additional SVR4 variants might not be too --> hard to add. @@ -243,7 +243,7 @@ void GC_register_dynamic_libraries() # endif /* SUNOS */ #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ - (defined(NETBSD) && defined(__ELF__)) + (defined(NETBSD) && defined(__ELF__)) || defined(HURD) #ifdef USE_PROC_FOR_LIBRARIES @@ -202,15 +202,27 @@ signed_word * log_size_ptr; } new_dl = (struct disappearing_link *) GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); - if (new_dl != 0) { - new_dl -> dl_hidden_obj = HIDE_POINTER(obj); - new_dl -> dl_hidden_link = HIDE_POINTER(link); - dl_set_next(new_dl, dl_head[index]); - dl_head[index] = new_dl; - GC_dl_entries++; - } else { - GC_finalization_failures++; + if (0 == new_dl) { +# ifdef THREADS + UNLOCK(); + ENABLE_SIGNALS(); +# endif + new_dl == GC_oom_fn(sizeof(struct disappearing_link)); + if (0 == new_dl) { + GC_finalization_failures++; + return(0); + } + /* It's not likely we'll make it here, but ... */ +# ifdef THREADS + DISABLE_SIGNALS(); + LOCK(); +# endif } + new_dl -> dl_hidden_obj = HIDE_POINTER(obj); + new_dl -> dl_hidden_link = HIDE_POINTER(link); + dl_set_next(new_dl, dl_head[index]); + dl_head[index] = new_dl; + GC_dl_entries++; # ifdef THREADS UNLOCK(); ENABLE_SIGNALS(); @@ -245,7 +257,7 @@ signed_word * log_size_ptr; UNLOCK(); ENABLE_SIGNALS(); # ifdef DBG_HDRS_ALL - dl_next(curr_dl) = 0; + dl_set_next(curr_dl, 0); # else GC_free((GC_PTR)curr_dl); # endif @@ -416,18 +428,30 @@ finalization_mark_proc * mp; } new_fo = (struct finalizable_object *) GC_INTERNAL_MALLOC(sizeof(struct finalizable_object),NORMAL); - if (new_fo != 0) { - new_fo -> fo_hidden_base = (word)HIDE_POINTER(base); - new_fo -> fo_fn = fn; - new_fo -> fo_client_data = (ptr_t)cd; - new_fo -> fo_object_size = hhdr -> hb_sz; - new_fo -> fo_mark_proc = mp; - fo_set_next(new_fo, fo_head[index]); - GC_fo_entries++; - fo_head[index] = new_fo; - } else { - GC_finalization_failures++; + if (0 == new_fo) { +# ifdef THREADS + UNLOCK(); + ENABLE_SIGNALS(); +# endif + new_fo == GC_oom_fn(sizeof(struct finalizable_object)); + if (0 == new_fo) { + GC_finalization_failures++; + return; + } + /* It's not likely we'll make it here, but ... */ +# ifdef THREADS + DISABLE_SIGNALS(); + LOCK(); +# endif } + new_fo -> fo_hidden_base = (word)HIDE_POINTER(base); + new_fo -> fo_fn = fn; + new_fo -> fo_client_data = (ptr_t)cd; + new_fo -> fo_object_size = hhdr -> hb_sz; + new_fo -> fo_mark_proc = mp; + fo_set_next(new_fo, fo_head[index]); + GC_fo_entries++; + fo_head[index] = new_fo; # ifdef THREADS UNLOCK(); ENABLE_SIGNALS(); @@ -593,7 +617,7 @@ void GC_finalize() GC_words_finalized += ALIGNED_WORDS(curr_fo -> fo_object_size) + ALIGNED_WORDS(sizeof(struct finalizable_object)); - GC_ASSERT(GC_is_marked((ptr_t)curr_fo)); + GC_ASSERT(GC_is_marked(GC_base((ptr_t)curr_fo))); curr_fo = next_fo; } else { prev_fo = curr_fo; diff --git a/include/gc.h b/include/gc.h index 08952566..aaf29ee3 100644 --- a/include/gc.h +++ b/include/gc.h @@ -80,10 +80,6 @@ typedef long ptrdiff_t; /* ptrdiff_t is not defined */ # endif -#if defined(__CYGWIN32__) && defined(GC_USE_DLL) -#include "libgc_globals.h" -#endif - #if defined(__MINGW32__) && defined(WIN32_THREADS) # ifdef GC_BUILD # define GC_API __declspec(dllexport) @@ -93,7 +89,7 @@ #endif #if (defined(__DMC__) || defined(_MSC_VER)) \ - && (defined(_DLL) && !defined(NOT_GC_DLL) \ + && (defined(_DLL) && !defined(GC_NOT_DLL) \ || defined(GC_DLL)) # ifdef GC_BUILD # define GC_API extern __declspec(dllexport) @@ -348,6 +344,10 @@ GC_API void GC_end_stubborn_change GC_PROTO((GC_PTR)); /* Return a pointer to the base (lowest address) of an object given */ /* a pointer to a location within the object. */ +/* I.e. map an interior pointer to the corresponding bas pointer. */ +/* Note that with debugging allocation, this returns a pointer to the */ +/* actual base of the object, i.e. the debug information, not to */ +/* the base of the user object. */ /* Return 0 if displaced_pointer doesn't point to within a valid */ /* object. */ GC_API GC_PTR GC_base GC_PROTO((GC_PTR displaced_pointer)); diff --git a/include/gc_cpp.h b/include/gc_cpp.h index a0f566f7..ceb73f50 100644 --- a/include/gc_cpp.h +++ b/include/gc_cpp.h @@ -83,7 +83,7 @@ Cautions: 1. Be sure the collector has been augmented with "make c++". 2. If your compiler supports the new "operator new[]" syntax, then -add -DOPERATOR_NEW_ARRAY to the Makefile. +add -DGC_OPERATOR_NEW_ARRAY to the Makefile. If your compiler doesn't support "operator new[]", beware that an array of type T, where T is derived from "gc", may or may not be @@ -137,10 +137,17 @@ by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. #define _cdecl #endif -#if ! defined( OPERATOR_NEW_ARRAY ) \ - && (__BORLANDC__ >= 0x450 || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6) \ - || __WATCOMC__ >= 1050 || _MSC_VER >= 1100 || _ENABLE_ARRAYNEW) -# define OPERATOR_NEW_ARRAY +#if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \ + && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \ + && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \ + || (defined(__GNUC__) && \ + (__GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 6)) \ + || (defined(__WATCOMC__) && __WATCOMC__ < 1050)) +# define GC_NO_OPERATOR_NEW_ARRAY +#endif + +#if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY) +# define GC_OPERATOR_NEW_ARRAY #endif enum GCPlacement {UseGC, @@ -154,11 +161,11 @@ class gc {public: inline void* operator new( size_t size, GCPlacement gcp ); inline void operator delete( void* obj ); -#ifdef OPERATOR_NEW_ARRAY +#ifdef GC_OPERATOR_NEW_ARRAY inline void* operator new[]( size_t size ); inline void* operator new[]( size_t size, GCPlacement gcp ); inline void operator delete[]( void* obj ); -#endif /* OPERATOR_NEW_ARRAY */ +#endif /* GC_OPERATOR_NEW_ARRAY */ }; /* Instances of classes derived from "gc" will be allocated in the @@ -204,7 +211,7 @@ inline void* operator new( classes derived from "gc_cleanup" or containing members derived from "gc_cleanup". */ -#ifdef OPERATOR_NEW_ARRAY +#ifdef GC_OPERATOR_NEW_ARRAY #ifdef _MSC_VER /** This ensures that the system default operator new[] doesn't get @@ -257,7 +264,7 @@ inline void* operator new[]( /* The operator new for arrays, identical to the above. */ -#endif /* OPERATOR_NEW_ARRAY */ +#endif /* GC_OPERATOR_NEW_ARRAY */ /**************************************************************************** @@ -280,7 +287,7 @@ inline void gc::operator delete( void* obj ) { GC_FREE( obj );} -#ifdef OPERATOR_NEW_ARRAY +#ifdef GC_OPERATOR_NEW_ARRAY inline void* gc::operator new[]( size_t size ) { return gc::operator new( size );} @@ -291,7 +298,7 @@ inline void* gc::operator new[]( size_t size, GCPlacement gcp ) { inline void gc::operator delete[]( void* obj ) { gc::operator delete( obj );} -#endif /* OPERATOR_NEW_ARRAY */ +#endif /* GC_OPERATOR_NEW_ARRAY */ inline gc_cleanup::~gc_cleanup() { @@ -332,7 +339,7 @@ inline void* operator new( return obj;} -#ifdef OPERATOR_NEW_ARRAY +#ifdef GC_OPERATOR_NEW_ARRAY inline void* operator new[]( size_t size, @@ -342,7 +349,7 @@ inline void* operator new[]( { return ::operator new( size, gcp, cleanup, clientData );} -#endif /* OPERATOR_NEW_ARRAY */ +#endif /* GC_OPERATOR_NEW_ARRAY */ #endif /* GC_CPP_H */ diff --git a/include/private/dbg_mlc.h b/include/private/dbg_mlc.h index 6932a82d..6f5b3c86 100644 --- a/include/private/dbg_mlc.h +++ b/include/private/dbg_mlc.h @@ -19,7 +19,7 @@ * not use it. Clients that define their own object kinds with * debugging allocators will probably want to include this, however. * No attempt is made to keep the namespace clean. This should not be - * included from header filrd that are frequently included by clients. + * included from header files that are frequently included by clients. */ #ifndef _DBG_MLC_H @@ -68,6 +68,9 @@ typedef struct { /* overwrite a value with the least significant */ /* bit clear, thus ensuring that we never overwrite */ /* a free list link field. */ + /* Note that blocks dropped by black-listing will */ + /* also have the lsb clear once debugging has */ + /* started. */ /* The following are special back pointer values. */ /* Note that the "hidden" (i.e. bitwise */ /* complemented version) of these is actually */ diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index bc1dbea8..5135e3e9 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -634,7 +634,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. */ diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 3bc2a48d..a0d12c84 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -350,6 +350,14 @@ # define S370 # define mach_type_known # endif +# if defined(__GNU__) +# if defined(__i386__) +/* The Debian Hurd running on generic PC */ +# define HURD +# define I386 +# define mach_type_known +# endif +# endif /* Feel free to add more clauses here */ @@ -497,6 +505,14 @@ * word stores of 0 are used instead. */ +/* If we are using a recent version of gcc, we can use __builtin_unwind_init() + * to push the relevant registers onto the stack. This generally makes + * USE_GENERIC_PUSH_REGS the preferred approach for marking from registers. + */ +# if defined(__GNUC__) && ((__GNUC__ >= 3) || \ + (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +# define HAVE_BUILTIN_UNWIND_INIT +# endif # define STACK_GRAN 0x1000000 # ifdef M68K @@ -804,6 +820,9 @@ # define ALIGN_DOUBLE /* Not strictly necessary, but may give speed */ /* improvement on Pentiums. */ # endif +# ifdef HAVE_BUILTIN_UNWIND_INIT +# define USE_GENERIC_PUSH_REGS +# endif # ifdef SEQUENT # define OS_TYPE "SEQUENT" extern int etext; @@ -1023,6 +1042,17 @@ # define DATASTART ((ptr_t) &__nullarea) # define DATAEND ((ptr_t) &_end) # endif +# ifdef HURD +# define OS_TYPE "HURD" +# define STACK_GROWS_DOWN +# define HEURISTIC2 + extern int __data_start; +# define DATASTART ( (ptr_t) (&__data_start)) + extern int _end; +# define DATAEND ( (ptr_t) (&_end)) +/* # define MPROTECT_VDB Not quite working yet? */ +# define DYNAMIC_LOADING +# endif # endif # ifdef NS32K @@ -1039,7 +1069,6 @@ # ifdef MIPS # define MACH_TYPE "MIPS" -/* # define STACKBOTTOM ((ptr_t)0x7fff8000) sometimes also works. */ # ifdef LINUX /* This was developed for a linuxce style platform. Probably */ /* needs to be tweaked for workstation class machines. */ @@ -1047,8 +1076,9 @@ extern int __data_start; # define DATASTART ((ptr_t)(&__data_start)) # define ALIGNMENT 4 -# define USE_GENERIC_PUSH_REGS 1 -# define STACKBOTTOM 0x80000000 +# define USE_GENERIC_PUSH_REGS +# define STACKBOTTOM ((ptr_t)0x7fff8000) + /* Older toolchains may need 0x80000000. */ /* In many cases, this should probably use LINUX_STACKBOTTOM */ /* instead. But some kernel versions seem to give the wrong */ /* value from /proc. */ @@ -1106,7 +1136,7 @@ # define ALIGNMENT 4 # define OS_TYPE "NETBSD" # define HEURISTIC2 -# define USE_GENERIC_PUSH_REGS 1 +# define USE_GENERIC_PUSH_REGS # ifdef __ELF__ extern int etext; # define DATASTART GC_data_start diff --git a/linux_threads.c b/linux_threads.c index 18891e7f..074be891 100644 --- a/linux_threads.c +++ b/linux_threads.c @@ -167,15 +167,16 @@ typedef struct GC_Thread_Rep { # ifdef THREAD_LOCAL_ALLOC # if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE) # define GRANULARITY 16 -# define NFREELISTS 48 +# define NFREELISTS 49 # else # define GRANULARITY 8 -# define NFREELISTS 64 +# define NFREELISTS 65 # endif - /* The ith free list corresponds to size (i+1)*GRANULARITY */ -# define INDEX_FROM_BYTES(n) (ADD_SLOP(n) - 1)/GRANULARITY -# define BYTES_FROM_INDEX(i) (((i) + 1) * GRANULARITY - EXTRA_BYTES) -# define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= NFREELISTS*GRANULARITY) + /* The ith free list corresponds to size i*GRANULARITY */ +# define INDEX_FROM_BYTES(n) ((ADD_SLOP(n) + GRANULARITY - 1)/GRANULARITY) +# define BYTES_FROM_INDEX(i) ((i) * GRANULARITY - EXTRA_BYTES) +# define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= \ + (NFREELISTS-1)*GRANULARITY) ptr_t ptrfree_freelists[NFREELISTS]; ptr_t normal_freelists[NFREELISTS]; # ifdef GC_GCJ_SUPPORT @@ -229,8 +230,8 @@ static void return_freelists(ptr_t *fl, ptr_t *gfl) ptr_t q, *qptr; size_t nwords; - for (i = 0; i < NFREELISTS; ++i) { - nwords = (i + 1) * (GRANULARITY/sizeof(word)); + for (i = 1; i < NFREELISTS; ++i) { + nwords = i * (GRANULARITY/sizeof(word)); qptr = fl + i; q = *qptr; if ((word)q < HBLKSIZE) continue; @@ -249,6 +250,12 @@ static void return_freelists(ptr_t *fl, ptr_t *gfl) } } +/* We statically allocate a single "size 0" object. It is linked to */ +/* itself, and is thus repeatedly reused for all size 0 allocation */ +/* requests. (Size 0 gcj allocation requests are incorrect, and */ +/* we arrange for those to fault asap.) */ +static ptr_t size_zero_object = (ptr_t)(&size_zero_object); + /* Each thread structure must be initialized. */ /* This call must be made from the new thread. */ /* Caller holds allocation lock. */ @@ -265,13 +272,19 @@ void GC_init_thread_local(GC_thread p) if (0 != GC_setspecific(GC_thread_key, p)) { ABORT("Failed to set thread specific allocation pointers"); } - for (i = 0; i < NFREELISTS; ++i) { + for (i = 1; i < NFREELISTS; ++i) { p -> ptrfree_freelists[i] = (ptr_t)1; p -> normal_freelists[i] = (ptr_t)1; # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[i] = (ptr_t)1; # endif } + /* Set up the size 0 free lists. */ + p -> ptrfree_freelists[0] = (ptr_t)(&size_zero_object); + p -> normal_freelists[0] = (ptr_t)(&size_zero_object); +# ifdef GC_GCJ_SUPPORT + p -> gcj_freelists[0] = (ptr_t)(-1); +# endif } #ifdef GC_GCJ_SUPPORT @@ -664,7 +677,7 @@ void GC_mark_thread_local_free_lists(void) for (i = 0; i < THREAD_TABLE_SZ; ++i) { for (p = GC_threads[i]; 0 != p; p = p -> next) { - for (j = 0; j < NFREELISTS; ++j) { + for (j = 1; j < NFREELISTS; ++j) { q = p -> ptrfree_freelists[j]; if ((word)q > HBLKSIZE) GC_set_fl_marks(q); q = p -> normal_freelists[j]; @@ -228,7 +228,7 @@ void GC_push_regs() && !(defined(NETBSD) && defined(__ELF__)) \ && !(defined(OPENBSD) && defined(__ELF__)) \ && !(defined(BEOS) && defined(__ELF__)) \ - && !defined(DOS4GW) + && !defined(DOS4GW) && !defined(HURD) /* I386 code, generic code does not appear to work */ /* It does appear to work under OS2, and asms dont */ /* This is used for some 38g UNIX variants and for CYGWIN32 */ @@ -244,7 +244,8 @@ void GC_push_regs() # if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \ || ( defined(I386) && defined(FREEBSD) && defined(__ELF__) ) \ || ( defined(I386) && defined(NETBSD) && defined(__ELF__) ) \ - || ( defined(I386) && defined(OPENBSD) && defined(__ELF__) ) + || ( defined(I386) && defined(OPENBSD) && defined(__ELF__) ) \ + || ( defined(I386) && defined(HURD) && defined(__ELF__) ) /* This is modified for Linux with ELF (Note: _ELF_ only) */ /* This section handles FreeBSD with ELF. */ @@ -391,8 +392,8 @@ void GC_push_regs() # endif /* other machines... */ -# if !(defined M68K) && !(defined VAX) && !(defined RT) -# if !(defined SPARC) && !(defined I386) && !(defined NS32K) +# if !defined(M68K) && !defined(VAX) && !defined(RT) +# if !defined(SPARC) && !defined(I386) && !defined(NS32K) # if !defined(POWERPC) && !defined(UTS4) # if !defined(PJ) && !(defined(MIPS) && defined(LINUX)) --> bad news <-- @@ -407,27 +408,35 @@ void GC_push_regs() void GC_generic_push_regs(cold_gc_frame) ptr_t cold_gc_frame; { - /* Generic code */ - /* The idea is due to Parag Patel at HP. */ - /* We're not sure whether he would like */ - /* to be he acknowledged for it or not. */ { - jmp_buf regs; - register word * i = (word *) regs; - register ptr_t lim = (ptr_t)(regs) + (sizeof regs); - - /* Setjmp on Sun 3s doesn't clear all of the buffer. */ - /* That tends to preserve garbage. Clear it. */ +# ifdef HAVE_BUILTIN_UNWIND_INIT + /* This was suggested by Richard Henderson as the way to */ + /* force callee-save registers and register windows onto */ + /* the stack. */ + __builtin_unwind_init(); +# else /* !HAVE_BUILTIN_UNWIND_INIT */ + /* Generic code */ + /* The idea is due to Parag Patel at HP. */ + /* We're not sure whether he would like */ + /* to be he acknowledged for it or not. */ + jmp_buf regs; + register word * i = (word *) regs; + register ptr_t lim = (ptr_t)(regs) + (sizeof regs); + + /* Setjmp doesn't always clear all of the buffer. */ + /* That tends to preserve garbage. Clear it. */ for (; (char *)i < lim; i++) { *i = 0; } -# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ - || defined(UTS4) || defined(LINUX) - (void) setjmp(regs); -# else - (void) _setjmp(regs); -# endif -# if defined(SPARC) || defined(IA64) +# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ + || defined(UTS4) || defined(LINUX) + (void) setjmp(regs); +# else + (void) _setjmp(regs); +# endif +# endif /* !HAVE_BUILTIN_UNWIND_INIT */ +# if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ + || defined(IA64) /* On a register window machine, we need to save register */ /* contents on the stack for this to work. The setjmp */ /* is probably not needed on SPARC, since pointers are */ @@ -438,6 +447,10 @@ ptr_t cold_gc_frame; word GC_save_regs_in_stack(); GC_save_regs_ret_val = GC_save_regs_in_stack(); + /* On IA64 gcc, could use __builtin_ia64_flushrs() and */ + /* __builtin_ia64_flushrs(). The latter will be done */ + /* implicitly by __builtin_unwind_init() for gcc3.0.1 */ + /* and later. */ } # endif GC_push_current_stack(cold_gc_frame); @@ -511,7 +524,7 @@ ptr_t cold_gc_frame; /* returns arg. Stack clearing is crucial on SPARC, so we supply */ /* an assembly version that's more careful. Assumes limit is hotter */ /* than sp, and limit is 8 byte aligned. */ -#if defined(ASM_CLEAR_CODE) && !defined(THREADS) +#if defined(ASM_CLEAR_CODE) #ifndef SPARC --> fix it #endif @@ -45,7 +45,7 @@ mutex_t GC_allocate_ml; /* Implicitly initialized. */ # else # ifdef WIN32_THREADS -# if defined(_DLL) || defined(GC_DLL) +# if !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL)) __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml; # else CRITICAL_SECTION GC_allocate_ml; @@ -301,6 +301,8 @@ ptr_t arg; if (++random_no % 13 == 0) { limit = sp; MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word)); + limit &= ~0xf; /* Make it sufficiently aligned for assembly */ + /* implementations of GC_clear_stack_inner. */ return GC_clear_stack_inner(arg, limit); } else { BZERO(dummy, SMALL_CLEAR_SIZE*sizeof(word)); @@ -691,7 +693,7 @@ out: } int GC_write(buf, len) - char * buf; + GC_CONST char * buf; size_t len; { BOOL tmp; @@ -63,25 +63,24 @@ /* Blatantly OS dependent routines, except for those that are related */ /* to dynamic loading. */ -# if !defined(THREADS) && !defined(STACKBOTTOM) && defined(HEURISTIC2) +# if defined(HEURISTIC2) || defined(SEARCH_FOR_DATA_START) # define NEED_FIND_LIMIT # endif -# if defined(IRIX_THREADS) || defined(HPUX_THREADS) +# if !defined(STACKBOTTOM) && defined(HEURISTIC2) # define NEED_FIND_LIMIT # endif -# if (defined(SUNOS4) && defined(DYNAMIC_LOADING)) && !defined(PCR) +# if defined(IRIX_THREADS) || defined(HPUX_THREADS) # define NEED_FIND_LIMIT # endif -# if (defined(SVR4) || defined(AUX) || defined(DGUX)) && !defined(PCR) +# if (defined(SUNOS4) && defined(DYNAMIC_LOADING)) && !defined(PCR) # define NEED_FIND_LIMIT # endif -# if defined(LINUX) && \ - (defined(POWERPC) || defined(SPARC) || defined(ALPHA) || defined(IA64) \ - || defined(MIPS)) +# if (defined(SVR4) || defined(AUX) || defined(DGUX) \ + || (defined(LINUX) && defined(SPARC))) && !defined(PCR) # define NEED_FIND_LIMIT # endif @@ -123,8 +122,10 @@ # include <fcntl.h> #endif -#ifdef SUNOS5SIGS -# include <sys/siginfo.h> +#if defined(SUNOS5SIGS) || defined (HURD) || defined(LINUX) +# ifdef SUNOS5SIGS +# include <sys/siginfo.h> +# endif # undef setjmp # undef longjmp # define setjmp(env) sigsetjmp(env, 1) @@ -338,7 +339,7 @@ void GC_enable_signals(void) && !defined(MSWINCE) \ && !defined(MACOS) && !defined(DJGPP) && !defined(DOS4GW) -# if defined(sigmask) && !defined(UTS4) +# if defined(sigmask) && !defined(UTS4) && !defined(HURD) /* Use the traditional BSD interface */ # define SIGSET_T int # define SIG_DEL(set, signal) (set) &= ~(sigmask(signal)) @@ -519,7 +520,7 @@ ptr_t GC_get_stack_base() # undef GC_AMIGA_SB # endif /* AMIGA */ -# if defined(NEED_FIND_LIMIT) || defined(UNIX_LIKE) +# if defined(NEED_FIND_LIMIT) || (defined(UNIX_LIKE) && !defined(ECOS)) # ifdef __STDC__ typedef void (*handler)(int); @@ -527,9 +528,9 @@ ptr_t GC_get_stack_base() typedef void (*handler)(); # endif -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) +# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) || defined(HURD) static struct sigaction old_segv_act; -# if defined(_sigargs) || defined(HPUX) /* !Irix6.x */ +# if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) || defined(HURD) static struct sigaction old_bus_act; # endif # else @@ -543,12 +544,16 @@ ptr_t GC_get_stack_base() handler h; # endif { -# ifndef ECOS -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) +# if defined(SUNOS5SIGS) || defined(IRIX5) \ + || defined(OSF1) || defined(HURD) struct sigaction act; act.sa_handler = h; - act.sa_flags = SA_RESTART | SA_NODEFER; +# ifdef SUNOS5SIGS + act.sa_flags = SA_RESTART | SA_NODEFER; +# else + act.sa_flags = SA_RESTART; +# endif /* The presence of SA_NODEFER represents yet another gross */ /* hack. Under Solaris 2.3, siglongjmp doesn't appear to */ /* interact correctly with -lthread. We hide the confusion */ @@ -564,7 +569,7 @@ ptr_t GC_get_stack_base() # else (void) sigaction(SIGSEGV, &act, &old_segv_act); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HPUX) + || defined(HPUX) || defined(HURD) /* Under Irix 5.x or HP/UX, we may get SIGBUS. */ /* Pthreads doesn't exist under Irix 5.x, so we */ /* don't have to worry in the threads case. */ @@ -577,7 +582,6 @@ ptr_t GC_get_stack_base() old_bus_handler = signal(SIGBUS, h); # endif # endif -# endif /* ECOS */ } # endif /* NEED_FIND_LIMIT || UNIX_LIKE */ @@ -600,11 +604,11 @@ ptr_t GC_get_stack_base() void GC_reset_fault_handler() { -# ifndef ECOS -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) +# if defined(SUNOS5SIGS) || defined(IRIX5) \ + || defined(OSF1) || defined(HURD) (void) sigaction(SIGSEGV, &old_segv_act, 0); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HPUX) + || defined(HPUX) || defined(HURD) (void) sigaction(SIGBUS, &old_bus_act, 0); # endif # else @@ -613,7 +617,6 @@ ptr_t GC_get_stack_base() (void) signal(SIGBUS, old_bus_handler); # endif # endif -# endif /* ECOS */ } /* Return the first nonaddressible location > p (up) or */ @@ -622,7 +625,6 @@ ptr_t GC_get_stack_base() ptr_t p; GC_bool up; { -# ifndef ECOS static VOLATILE ptr_t result; /* Needs to be static, since otherwise it may not be */ /* preserved across the longjmp. Can safely be */ @@ -648,14 +650,9 @@ ptr_t GC_get_stack_base() result += MIN_PAGE_SIZE; } return(result); -# else /* ECOS */ - abort(); -# endif /* ECOS */ } # endif -# ifndef ECOS - #ifdef LINUX_STACKBOTTOM #include <sys/types.h> @@ -753,7 +750,7 @@ ptr_t GC_get_stack_base() #endif /* FREEBSD_STACKBOTTOM */ #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \ - && !defined(MSWINCE) && !defined(OS2) + && !defined(MSWINCE) && !defined(OS2) && !defined(ECOS) ptr_t GC_get_stack_base() { @@ -807,7 +804,6 @@ ptr_t GC_get_stack_base() return(result); # endif /* STACKBOTTOM */ } -# endif /* ECOS */ # endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS */ @@ -1808,7 +1804,8 @@ struct hblk *h; #if defined(SUNOS4) || defined(FREEBSD) typedef void (* SIG_PF)(); #endif -#if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) || defined(MACOSX) +#if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \ + || defined(MACOSX) || defined(HURD) # ifdef __STDC__ typedef void (* SIG_PF)(int); # else @@ -1826,7 +1823,7 @@ struct hblk *h; # define SIG_DFL (SIG_PF) (-1) #endif -#if defined(IRIX5) || defined(OSF1) +#if defined(IRIX5) || defined(OSF1) || defined(HURD) typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *); #endif #if defined(SUNOS5SIGS) @@ -2013,7 +2010,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ #ifdef GC_TEST_AND_SET_DEFINED static VOLATILE unsigned int fault_handler_lock = 0; void async_set_pht_entry_from_index(VOLATILE page_hash_table db, int index) { - while (GC_test_and_set(&fault_handler_lock)); + while (GC_test_and_set(&fault_handler_lock)) {} /* Could also revert to set_pht_entry_from_index_safe if initial */ /* GC_test_and_set fails. */ set_pht_entry_from_index(db, index); @@ -2067,16 +2064,21 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # define CODE_OK (code == BUS_PAGE_FAULT) # endif # endif -# if defined(IRIX5) || defined(OSF1) +# if defined(IRIX5) || defined(OSF1) || defined(HURD) # include <errno.h> void GC_write_fault_handler(int sig, int code, struct sigcontext *scp) -# define SIG_OK (sig == SIGSEGV) # ifdef OSF1 +# define SIG_OK (sig == SIGSEGV) # define CODE_OK (code == 2 /* experimentally determined */) # endif # ifdef IRIX5 +# define SIG_OK (sig == SIGSEGV) # define CODE_OK (code == EACCES) # endif +# ifdef HURD +# define SIG_OK (sig == SIGBUS || sig == SIGSEGV) +# define CODE_OK TRUE +# endif # endif # if defined(LINUX) # if defined(ALPHA) || defined(M68K) @@ -2131,6 +2133,9 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # endif { register unsigned i; +# if defined(HURD) + char *addr = (char *) code; +# endif # ifdef IRIX5 char * addr = (char *) (size_t) (scp -> sc_badvaddr); # endif @@ -2254,7 +2259,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # endif return; # endif -# if defined (IRIX5) || defined(OSF1) +# if defined (IRIX5) || defined(OSF1) || defined(HURD) (*(REAL_SIG_PF)old_handler) (sig, code, scp); return; # endif @@ -2332,13 +2337,14 @@ struct hblk *h; void GC_dirty_init() { -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) || defined(OSF1) +# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) || \ + defined(OSF1) || defined(HURD) 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) +# if defined(IRIX5) || defined(LINUX) || defined(OSF1) || defined(HURD) act.sa_flags = SA_RESTART; - act.sa_handler = GC_write_fault_handler; + act.sa_handler = (SIG_PF)GC_write_fault_handler; # else act.sa_flags = SA_RESTART | SA_SIGINFO; act.sa_sigaction = GC_write_fault_handler; @@ -2390,7 +2396,8 @@ void GC_dirty_init() # endif } # endif -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) || defined(OSF1) +# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \ + || defined(OSF1) || defined(HURD) /* SUNOS5SIGS includes HPUX */ # if defined(IRIX_THREADS) sigaction(SIGSEGV, 0, &oldact); @@ -2398,7 +2405,7 @@ void GC_dirty_init() # else sigaction(SIGSEGV, &act, &oldact); # endif -# if defined(_sigargs) +# if defined(_sigargs) || defined(HURD) /* This is Irix 5.x, not 6.x. Irix 5.x does not have */ /* sa_sigaction. */ GC_old_segv_handler = oldact.sa_handler; @@ -2419,7 +2426,7 @@ void GC_dirty_init() # endif } # endif -# if defined(MACOSX) || defined(HPUX) || defined(LINUX) +# if defined(MACOSX) || defined(HPUX) || defined(LINUX) || defined(HURD) sigaction(SIGBUS, &act, &oldact); GC_old_bus_handler = oldact.sa_handler; if (GC_old_bus_handler == SIG_IGN) { @@ -2568,10 +2575,14 @@ word len; result = readv(fd, &iov, 1); } # else +# if defined(HURD) + result = __read(fd, buf, nbyte); +# else /* The two zero args at the end of this list are because one IA-64 syscall() implementation actually requires six args to be passed, even though they aren't always used. */ result = syscall(SYS_read, fd, buf, nbyte, 0, 0); +# endif /* !HURD */ # endif GC_end_syscall(); return(result); diff --git a/powerpc_macosx_mach_dep.s b/powerpc_macosx_mach_dep.s index 72cdfdc8..92f06286 100755 --- a/powerpc_macosx_mach_dep.s +++ b/powerpc_macosx_mach_dep.s @@ -16,10 +16,10 @@ _GC_push_regs: stw r0,8(r1) ; save return address stwu r1,-spaceToSave(r1) ; skip over caller save area ; - mr r3,r2 ; mark from r2. Well I'm not really sure + mr r3,r2 ; mark from r2. Well Im not really sure ; that this is necessary or even the right - ; thing to do - at least it doesn't harm... - ; According to Apple's docs it points to + ; thing to do - at least it doesnt harm... + ; According to Apples docs it points to ; the direct data area, whatever that is... bl L_GC_push_one$stub mr r3,r13 ; mark from r13-r31 @@ -1,6 +1,6 @@ #define GC_VERSION_MAJOR 6 #define GC_VERSION_MINOR 0 -#define GC_ALPHA_VERSION 8 +#define GC_ALPHA_VERSION GC_NOT_ALPHA # define GC_NOT_ALPHA 0xff |