aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/include
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2001-08-18 01:04:43 +0000
committerTom Tromey <tromey@gcc.gnu.org>2001-08-18 01:04:43 +0000
commit5a2586cf8fcf001cddb47d3f9bf6610975d1564d (patch)
tree0a038d94cc4acd44c0926f011247f6b7969fa84b /boehm-gc/include
parenteed566698034311c58eea585da1ddb5a6e0807fb (diff)
downloadgcc-5a2586cf8fcf001cddb47d3f9bf6610975d1564d.zip
gcc-5a2586cf8fcf001cddb47d3f9bf6610975d1564d.tar.gz
gcc-5a2586cf8fcf001cddb47d3f9bf6610975d1564d.tar.bz2
Makefile.am, [...]: Imported GC 6.0 and merged local changes.
* Makefile.am, acinclude.m4, configure.in: Imported GC 6.0 and merged local changes. From-SVN: r44994
Diffstat (limited to 'boehm-gc/include')
-rw-r--r--boehm-gc/include/gc.h15
-rw-r--r--boehm-gc/include/gc_cpp.h38
-rw-r--r--boehm-gc/include/private/dbg_mlc.h47
-rw-r--r--boehm-gc/include/private/gc_hdrs.h102
-rw-r--r--boehm-gc/include/private/gc_locks.h3
-rw-r--r--boehm-gc/include/private/gc_pmark.h61
-rw-r--r--boehm-gc/include/private/gc_priv.h52
-rw-r--r--boehm-gc/include/private/gcconfig.h46
8 files changed, 191 insertions, 173 deletions
diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h
index b1449f5..aaf29ee 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 6aacd0a..ceb73f5 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 1ee814d..6f5b3c8 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 6966a9a..dd61545 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 b9ff0cf..eed9f10 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 0eec533..43077e9 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 d06cd8b..5135e3e 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 0f7fe24..e8bac1b 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) || \