diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-08-18 01:04:43 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-08-18 01:04:43 +0000 |
commit | 8fee6c5ba203062646a84ef04770c79ba2be0a6a (patch) | |
tree | 0a038d94cc4acd44c0926f011247f6b7969fa84b /boehm-gc/include | |
parent | 75ae025532a15d2842c5401959ef6775e3ebe550 (diff) | |
download | gcc-8fee6c5ba203062646a84ef04770c79ba2be0a6a.tar.gz |
* Makefile.am, acinclude.m4, configure.in: Imported GC 6.0 and
merged local changes.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44994 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'boehm-gc/include')
-rw-r--r-- | boehm-gc/include/gc.h | 15 | ||||
-rw-r--r-- | boehm-gc/include/gc_cpp.h | 38 | ||||
-rw-r--r-- | boehm-gc/include/private/dbg_mlc.h | 47 | ||||
-rw-r--r-- | boehm-gc/include/private/gc_hdrs.h | 102 | ||||
-rw-r--r-- | boehm-gc/include/private/gc_locks.h | 3 | ||||
-rw-r--r-- | boehm-gc/include/private/gc_pmark.h | 61 | ||||
-rw-r--r-- | boehm-gc/include/private/gc_priv.h | 52 | ||||
-rw-r--r-- | boehm-gc/include/private/gcconfig.h | 46 |
8 files changed, 191 insertions, 173 deletions
diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index b1449f5dc8a..aaf29ee35ba 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/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) @@ -92,8 +88,9 @@ # endif #endif -#if defined(_MSC_VER) && (defined(_DLL) && !defined(NOT_GC_DLL) \ - || defined(GC_DLL)) +#if (defined(__DMC__) || defined(_MSC_VER)) \ + && (defined(_DLL) && !defined(GC_NOT_DLL) \ + || defined(GC_DLL)) # ifdef GC_BUILD # define GC_API extern __declspec(dllexport) # else @@ -347,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)); @@ -701,7 +702,7 @@ GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p)); /* Returns old warning procedure. */ /* The following is intended to be used by a higher level */ -/* (e.g. cedar-like) finalization facility. It is expected */ +/* (e.g. Java-like) finalization facility. It is expected */ /* that finalization code will arrange for hidden pointers to */ /* disappear. Otherwise objects can be accessed after they */ /* have been collected. */ diff --git a/boehm-gc/include/gc_cpp.h b/boehm-gc/include/gc_cpp.h index 6aacd0aea04..ceb73f50a65 100644 --- a/boehm-gc/include/gc_cpp.h +++ b/boehm-gc/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) -# 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() { @@ -305,11 +312,12 @@ inline gc_cleanup::gc_cleanup() { void* oldData; void* base = GC_base( (void *) this ); if (0 != base) { - GC_REGISTER_FINALIZER_IGNORE_SELF( + // Don't call the debug version, since this is a real base address. + GC_register_finalizer_ignore_self( base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base), &oldProc, &oldData ); if (0 != oldProc) { - GC_REGISTER_FINALIZER_IGNORE_SELF( base, oldProc, oldData, 0, 0 );}}} + GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );}}} inline void* operator new( size_t size, @@ -331,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, @@ -341,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/boehm-gc/include/private/dbg_mlc.h b/boehm-gc/include/private/dbg_mlc.h index 1ee814db19b..6f5b3c8677d 100644 --- a/boehm-gc/include/private/dbg_mlc.h +++ b/boehm-gc/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 @@ -32,11 +32,31 @@ # include "gc_backptr.h" # endif +#ifndef HIDE_POINTER + /* Gc.h was previously included, and hence the I_HIDE_POINTERS */ + /* definition had no effect. Repeat the gc.h definitions here to */ + /* get them anyway. */ + typedef GC_word GC_hidden_pointer; +# define HIDE_POINTER(p) (~(GC_hidden_pointer)(p)) +# define REVEAL_POINTER(p) ((GC_PTR)(HIDE_POINTER(p))) +#endif /* HIDE_POINTER */ + # define START_FLAG ((word)0xfedcedcb) # define END_FLAG ((word)0xbcdecdef) /* Stored both one past the end of user object, and one before */ /* the end of the object as seen by the allocator. */ +# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) + /* Pointer "source"s that aren't real locations. */ + /* Used in oh_back_ptr fields and as "source" */ + /* argument to some marking functions. */ +# define NOT_MARKED (ptr_t)(0) +# define MARKED_FOR_FINALIZATION (ptr_t)(2) + /* Object was marked because it is finalizable. */ +# define MARKED_FROM_REGISTER (ptr_t)(4) + /* Object was marked from a rgister. Hence the */ + /* source of the reference doesn't have an address. */ +# endif /* KEEP_BACK_PTRS || PRINT_BLACK_LIST */ /* Object header */ typedef struct { @@ -48,16 +68,13 @@ 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 */ /* stored. */ -# define NOT_MARKED (ptr_t)(0) -# define MARKED_FOR_FINALIZATION (ptr_t)(2) - /* Object was marked because it is finalizable. */ -# define MARKED_FROM_REGISTER (ptr_t)(4) - /* Object was marked from a rgister. Hence the */ - /* source of the reference doesn't have an address. */ # if ALIGNMENT == 1 /* Fudge back pointer to be even. */ # define HIDE_BACK_PTR(p) HIDE_POINTER(~1 & (GC_word)(p)) @@ -68,7 +85,7 @@ typedef struct { word oh_dummy; # endif # endif - char * oh_string; /* object descriptor string */ + GC_CONST char * oh_string; /* object descriptor string */ word oh_int; /* object descriptor integers */ # ifdef NEED_CALLINFO struct callinfo oh_ci[NFRAMES]; @@ -81,13 +98,17 @@ typedef struct { /* The size of the above structure is assumed not to dealign things, */ /* and to be a multiple of the word length. */ -#define DEBUG_BYTES (sizeof (oh) + sizeof (word)) +#ifdef SHORT_DBG_HDRS +# define DEBUG_BYTES (sizeof (oh)) +#else + /* Add space for END_FLAG, but use any extra space that was already */ + /* added to catch off-the-end pointers. */ +# define DEBUG_BYTES (sizeof (oh) + sizeof (word) - EXTRA_BYTES) +#endif #define USR_PTR_FROM_BASE(p) ((ptr_t)(p) + sizeof(oh)) -/* There is no reason to ever add a byte at the end explicitly, since we */ -/* already add a guard word. */ -#undef ROUNDED_UP_WORDS -#define ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1) +/* Round bytes to words without adding extra byte at end. */ +#define SIMPLE_ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1) #ifdef SAVE_CALL_CHAIN # define ADD_CALL_CHAIN(base, ra) GC_save_callers(((oh *)(base)) -> oh_ci) diff --git a/boehm-gc/include/private/gc_hdrs.h b/boehm-gc/include/private/gc_hdrs.h index 6966a9a1a87..dd615455f3b 100644 --- a/boehm-gc/include/private/gc_hdrs.h +++ b/boehm-gc/include/private/gc_hdrs.h @@ -26,13 +26,11 @@ typedef struct hblkhdr hdr; * table. * * This defines HDR, GET_HDR, and SET_HDR, the main macros used to - * retrieve and set object headers. We also define some variants to - * retrieve 2 unrelated headers in interleaved fashion. This - * slightly improves scheduling. + * retrieve and set object headers. * * Since 5.0 alpha 5, we can also take advantage of a header lookup * cache. This is a locally declared direct mapped cache, used inside - * the marker. The HC_GET_HDR and HC_GET_HDR2 macros use and maintain this + * the marker. The HC_GET_HDR macro uses and maintains this * cache. Assuming we get reasonable hit rates, this shaves a few * memory references from each pointer validation. */ @@ -67,16 +65,13 @@ extern hdr * GC_invalid_header; /* header for an imaginary block */ /* Check whether p and corresponding hhdr point to long or invalid */ -/* object. If so, advance them to */ +/* object. If so, advance hhdr to */ /* beginning of block, or set hhdr to GC_invalid_header. */ #define ADVANCE(p, hhdr, source) \ - if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ - p = GC_FIND_START(p, hhdr, (word)source); \ - if (p == 0) { \ - hhdr = GC_invalid_header; \ - } else { \ - hhdr = GC_find_header(p); \ - } \ + { \ + hdr * new_hdr = GC_invalid_header; \ + p = GC_FIND_START(p, hhdr, &new_hdr, (word)source); \ + hhdr = new_hdr; \ } #ifdef USE_HDR_CACHE @@ -124,35 +119,12 @@ extern hdr * GC_invalid_header; /* header for an imaginary block */ } else { \ HC_MISS(); \ GET_HDR(p, hhdr); \ - ADVANCE(p, hhdr, source); \ - hce -> block_addr = (word)(p) >> LOG_HBLKSIZE; \ - hce -> hce_hdr = hhdr; \ - } \ - } - -# define HC_GET_HDR2(p1, hhdr1, source1, p2, hhdr2, source2) \ - { \ - hdr_cache_entry * hce1 = HCE(p1); \ - hdr_cache_entry * hce2 = HCE(p2); \ - if (HCE_VALID_FOR(hce1, p1)) { \ - HC_HIT(); \ - hhdr1 = hce1 -> hce_hdr; \ - } else { \ - HC_MISS(); \ - GET_HDR(p1, hhdr1); \ - ADVANCE(p1, hhdr1, source1); \ - hce1 -> block_addr = (word)(p1) >> LOG_HBLKSIZE; \ - hce1 -> hce_hdr = hhdr1; \ - } \ - if (HCE_VALID_FOR(hce2, p2)) { \ - HC_HIT(); \ - hhdr2 = hce2 -> hce_hdr; \ - } else { \ - HC_MISS(); \ - GET_HDR(p2, hhdr2); \ - ADVANCE(p2, hhdr2, source2); \ - hce2 -> block_addr = (word)(p2) >> LOG_HBLKSIZE; \ - hce2 -> hce_hdr = hhdr2; \ + if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ + ADVANCE(p, hhdr, source); \ + } else { \ + hce -> block_addr = (word)(p) >> LOG_HBLKSIZE; \ + hce -> hce_hdr = hhdr; \ + } \ } \ } @@ -165,16 +137,10 @@ extern hdr * GC_invalid_header; /* header for an imaginary block */ # define HC_GET_HDR(p, hhdr, source) \ { \ GET_HDR(p, hhdr); \ - ADVANCE(p, hhdr, source); \ - } - -# define HC_GET_HDR2(p1, hhdr1, source1, p2, hhdr2, source2) \ - { \ - GET_HDR2(p1, hhdr1, p2, hhdr2); \ - ADVANCE(p1, hhdr1, source1); \ - ADVANCE(p2, hhdr2, source2); \ + if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ + ADVANCE(p, hhdr, source); \ + } \ } - #endif typedef struct bi { @@ -229,8 +195,6 @@ typedef struct bi { # define GET_HDR(p, hhdr) (hhdr) = HDR(p) # define SET_HDR(p, hhdr) HDR_INNER(p) = (hhdr) # define GET_HDR_ADDR(p, ha) (ha) = &(HDR_INNER(p)) -# define GET_HDR2(p1, hhdr1, p2, hhdr2) \ - { GET_HDR(p1, hhdr1); GET_HDR(p2, hhdr2); } # else /* hash */ /* Hash function for tree top level */ # define TL_HASH(hi) ((hi) & (TOP_SZ - 1)) @@ -257,40 +221,6 @@ typedef struct bi { # define SET_HDR(p, hhdr) { register hdr ** _ha; GET_HDR_ADDR(p, _ha); \ *_ha = (hhdr); } # define HDR(p) GC_find_header((ptr_t)(p)) - /* And some interleaved versions for two pointers at once. */ - /* This hopefully helps scheduling on processors like IA64. */ -# define GET_BI2(p1, bottom_indx1, p2, bottom_indx2) \ - { \ - register word hi1 = \ - (word)(p1) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); \ - register word hi2 = \ - (word)(p2) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); \ - register bottom_index * _bi1 = GC_top_index[TL_HASH(hi1)]; \ - register bottom_index * _bi2 = GC_top_index[TL_HASH(hi2)]; \ - \ - while (_bi1 -> key != hi1 && _bi1 != GC_all_nils) \ - _bi1 = _bi1 -> hash_link; \ - while (_bi2 -> key != hi2 && _bi2 != GC_all_nils) \ - _bi2 = _bi2 -> hash_link; \ - (bottom_indx1) = _bi1; \ - (bottom_indx2) = _bi2; \ - } -# define GET_HDR_ADDR2(p1, ha1, p2, ha2) \ - { \ - register bottom_index * bi1; \ - register bottom_index * bi2; \ - \ - GET_BI2(p1, bi1, p2, bi2); \ - (ha1) = &(HDR_FROM_BI(bi1, p1)); \ - (ha2) = &(HDR_FROM_BI(bi2, p2)); \ - } -# define GET_HDR2(p1, hhdr1, p2, hhdr2) \ - { register hdr ** _ha1; \ - register hdr ** _ha2; \ - GET_HDR_ADDR2(p1, _ha1, p2, _ha2); \ - (hhdr1) = *_ha1; \ - (hhdr2) = *_ha2; \ - } # endif /* Is the result a forwarding address to someplace closer to the */ diff --git a/boehm-gc/include/private/gc_locks.h b/boehm-gc/include/private/gc_locks.h index b9ff0cf1933..eed9f1050f8 100644 --- a/boehm-gc/include/private/gc_locks.h +++ b/boehm-gc/include/private/gc_locks.h @@ -43,6 +43,7 @@ * */ # ifdef THREADS + void GC_noop1 GC_PROTO((word)); # ifdef PCR_OBSOLETE /* Faster, but broken with multiple lwp's */ # include "th/PCR_Th.h" # include "th/PCR_ThCrSec.h" @@ -236,7 +237,7 @@ /* "set" means 0 and "clear" means 1 here. */ # define GC_test_and_set(addr) !GC_test_and_clear(addr); # define GC_TEST_AND_SET_DEFINED -# define GC_clear(addr) GC_noop1(addr); *(volatile unsigned int *)addr = 1; +# define GC_clear(addr) GC_noop1((word)(addr)); *(volatile unsigned int *)addr = 1; /* The above needs a memory barrier! */ # define GC_CLEAR_DEFINED # endif diff --git a/boehm-gc/include/private/gc_pmark.h b/boehm-gc/include/private/gc_pmark.h index 0eec53376a8..43077e9f616 100644 --- a/boehm-gc/include/private/gc_pmark.h +++ b/boehm-gc/include/private/gc_pmark.h @@ -25,7 +25,7 @@ #ifndef GC_PMARK_H # define GC_PMARK_H -# ifdef KEEP_BACK_PTRS +# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) # include "dbg_mlc.h" # endif # ifndef GC_MARK_H @@ -132,12 +132,17 @@ extern mse * GC_mark_stack; */ #endif /* PARALLEL_MARK */ +/* Return a pointer to within 1st page of object. */ +/* Set *new_hdr_p to corr. hdr. */ +#ifdef __STDC__ # ifdef PRINT_BLACK_LIST - ptr_t GC_find_start(ptr_t current, hdr *hhdr, word source); + ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, word source); # else - ptr_t GC_find_start(ptr_t current, hdr *hhdr); -# define source 0 + ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p); # endif +#else + ptr_t GC_find_start(); +#endif mse *GC_signal_mark_stack_overflow(mse *msp); @@ -169,11 +174,11 @@ mse *GC_signal_mark_stack_overflow(mse *msp); } #ifdef PRINT_BLACK_LIST -# define GC_FIND_START(current, hhdr, source) \ - GC_find_start(current, hhdr, source) +# define GC_FIND_START(current, hhdr, new_hdr_p, source) \ + GC_find_start(current, hhdr, new_hdr_p, source) #else -# define GC_FIND_START(current, hhdr, source) \ - GC_find_start(current, hhdr) +# define GC_FIND_START(current, hhdr, new_hdr_p, source) \ + GC_find_start(current, hhdr, new_hdr_p) #endif /* Push the contents of current onto the mark stack if it is a valid */ @@ -188,9 +193,10 @@ mse *GC_signal_mark_stack_overflow(mse *msp); \ GET_HDR(my_current, my_hhdr); \ if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \ - my_current = GC_FIND_START(my_current, my_hhdr, (word)source); \ - if (my_current == 0) goto exit_label; \ - my_hhdr = GC_find_header(my_current); \ + hdr * new_hdr = GC_invalid_header; \ + my_current = GC_FIND_START(my_current, my_hhdr, \ + &new_hdr, (word)source); \ + my_hhdr = new_hdr; \ } \ PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ source, exit_label, my_hhdr); \ @@ -210,27 +216,6 @@ exit_label: ; \ exit_label: ; \ } -/* As above, but deal with two pointers in interleaved fashion. */ -# define HC_PUSH_CONTENTS2(current1, current2, mark_stack_top, \ - mark_stack_limit, \ - source1, source2, exit_label1, exit_label2) \ -{ \ - hdr * hhdr1; \ - ptr_t my_current1 = current1; \ - hdr * hhdr2; \ - ptr_t my_current2 = current2; \ - \ - HC_GET_HDR2(my_current1, hhdr1, source1, my_current2, hhdr2, source2); \ - PUSH_CONTENTS_HDR(my_current1, mark_stack_top, mark_stack_limit, \ - source1, exit_label1, hhdr1); \ -exit_label1: ; \ - if (0 != hhdr2) { \ - PUSH_CONTENTS_HDR(my_current2, mark_stack_top, mark_stack_limit, \ - source2, exit_label2, hhdr2); \ - } \ -exit_label2: ; \ -} - /* Set mark bit, exit if it was already set. */ # ifdef USE_MARK_BYTES @@ -257,10 +242,12 @@ exit_label2: ; \ # endif /* USE_MARK_BYTES */ /* If the mark bit corresponding to current is not set, set it, and */ -/* push the contents of the object on the mark stack. Since we */ -/* already have the header, we only look at the low order bits of */ -/* current. (The value of current doesn't matter if hhdr = */ -/* GC_invalid_header.) */ +/* push the contents of the object on the mark stack. For a small */ +/* object we assume that current is the (possibly interior) pointer */ +/* to the object. For large objects we assume that current points */ +/* to somewhere inside the first page of the object. If */ +/* GC_all_interior_pointers is set, it may have been previously */ +/* adjusted to make that true. */ # define PUSH_CONTENTS_HDR(current, mark_stack_top, mark_stack_limit, \ source, exit_label, hhdr) \ { \ @@ -346,7 +333,7 @@ mse * GC_mark_from GC_PROTO((mse * top, mse * bottom, mse *limit)); while (!GC_mark_stack_empty()) MARK_FROM_MARK_STACK(); \ if (GC_mark_state != MS_NONE) { \ GC_set_mark_bit(real_ptr); \ - while (!GC_mark_some((ptr_t)0)); \ + while (!GC_mark_some((ptr_t)0)) {} \ } \ } diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h index d06cd8b872c..5135e3e9b0a 100644 --- a/boehm-gc/include/private/gc_priv.h +++ b/boehm-gc/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. */ @@ -1456,6 +1456,9 @@ void GC_clear_hdr_marks GC_PROTO((hdr * hhdr)); /* Clear the mark bits in a header */ void GC_set_hdr_marks GC_PROTO((hdr * hhdr)); /* Set the mark bits in a header */ +void GC_set_fl_marks GC_PROTO((ptr_t p)); + /* Set all mark bits associated with */ + /* a free list. */ void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp)); GC_bool GC_is_static_root GC_PROTO((ptr_t p)); /* Is the address p in one of the registered static */ @@ -1484,9 +1487,9 @@ void GC_bl_init GC_PROTO((void)); /* reference from the heap or static data */ # define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \ if (GC_all_interior_pointers) { \ - GC_add_to_black_list_stack(bits, source); \ + GC_add_to_black_list_stack(bits, (ptr_t)(source)); \ } else { \ - GC_add_to_black_list_normal(bits, source); \ + GC_add_to_black_list_normal(bits, (ptr_t)(source)); \ } # else void GC_add_to_black_list_normal GC_PROTO((word p)); @@ -1796,12 +1799,16 @@ void GC_dump GC_PROTO((void)); /* Make arguments appear live to compiler */ # ifdef __WATCOMC__ - void GC_noop(void*, ...); + void GC_noop(void*, ...); # else - GC_API void GC_noop(); +# ifdef __DMC__ + GC_API void GC_noop(...); +# else + GC_API void GC_noop(); +# endif # endif -void GC_noop1 GC_PROTO((word arg)); +void GC_noop1 GC_PROTO((word)); /* Logging and diagnostic output: */ GC_API void GC_printf GC_PROTO((GC_CONST char * format, long, long, long, long, long, long)); @@ -1859,7 +1866,7 @@ void GC_err_puts GC_PROTO((GC_CONST char *s)); # define GC_ASSERT(expr) # endif -# ifdef PARALLEL_MARK +# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC) /* We need additional synchronization facilities from the thread */ /* support. We believe these are less performance critical */ /* than the main garbage collector lock; standard pthreads-based */ @@ -1878,13 +1885,15 @@ void GC_err_puts GC_PROTO((GC_CONST char *s)); extern void GC_acquire_mark_lock(); extern void GC_release_mark_lock(); - extern void GC_notify_all_marker(); extern void GC_notify_all_builder(); - extern void GC_wait_marker(); /* extern void GC_wait_builder(); */ extern void GC_wait_for_reclaim(); extern word GC_fl_builder_count; /* Protected by mark lock. */ +# endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ +# ifdef PARALLEL_MARK + extern void GC_notify_all_marker(); + extern void GC_wait_marker(); extern word GC_mark_no; /* Protected by mark lock. */ extern void GC_help_marker(word my_mark_no); @@ -1894,4 +1903,29 @@ void GC_err_puts GC_PROTO((GC_CONST char *s)); /* some other reason. */ # endif /* PARALLEL_MARK */ +# if defined(LINUX_THREADS) || defined(IRIX_THREADS) \ + || defined(HPUX_THREADS) || defined(OSF1_THREADS) + /* We define the thread suspension signal here, so that we can refer */ + /* to it in the dirty bit implementation, if necessary. Ideally we */ + /* would allocate a (real-time ?) signal using the standard mechanism.*/ + /* unfortunately, there is no standard mechanism. (There is one */ + /* in Linux glibc, but it's not exported.) Thus we continue to use */ + /* the same hard-coded signals we've always used. */ +# if !defined(SIG_SUSPEND) +# if defined(LINUX_THREADS) +# if defined(SPARC) && !defined(SIGPWR) + /* SPARC/Linux doesn't properly define SIGPWR in <signal.h>. + * It is aliased to SIGLOST in asm/signal.h, though. */ +# define SIG_SUSPEND SIGLOST +# else + /* Linuxthreads uses SIGUSR1 and SIGUSR2. */ +# define SIG_SUSPEND SIGPWR +# endif +# else /* !LINUX_THREADS */ +# define SIG_SUSPEND _SIGRTMIN + 6 +# endif +# endif /* !SIG_SUSPEND */ + +# endif + # endif /* GC_PRIVATE_H */ diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h index 0f7fe248073..e8bac1bcdc2 100644 --- a/boehm-gc/include/private/gcconfig.h +++ b/boehm-gc/include/private/gcconfig.h @@ -174,7 +174,7 @@ # define IA64 # define mach_type_known # endif -# if defined(LINUX) && defined(powerpc) +# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__)) # define POWERPC # define mach_type_known # endif @@ -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 @@ -1587,6 +1617,12 @@ # if defined(HPUX_THREADS) && !defined(HPUX) --> inconsistent configuration # endif +# if defined(WIN32_THREADS) && !defined(MSWIN32) + /* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect the necessary code */ + /* is mostly there, but nobody has actually made sure the right combination of pieces is */ + /* compiled in, etc. */ +--> inconsistent configuration +# endif # if defined(PCR) || defined(SRC_M3) || \ defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \ defined(IRIX_THREADS) || defined(LINUX_THREADS) || \ |