OSDN Git Service

2007-01-19 Andreas Tobler <a.tobler@schweiz.org>
[pf3gnuchains/gcc-fork.git] / boehm-gc / include / private / gc_priv.h
index b1526aa..41c75d3 100644 (file)
 # ifndef GC_PRIVATE_H
 # define GC_PRIVATE_H
 
+/* Autoconf definitions. */
+/* FIXME: This should really be included directly from each .c file. */
+#include <gc_config.h>
+
 #if defined(mips) && defined(SYSTYPE_BSD) && defined(sony_news)
     /* sony RISC NEWS, NEWSOS 4 */
 #   define BSD_TIME
 #   define BSD_TIME
 #endif
 
+#ifdef DGUX
+#   include <sys/types.h>
+#   include <sys/time.h>
+#   include <sys/resource.h>
+#endif /* DGUX */
+
 #ifdef BSD_TIME
 #   include <sys/types.h>
 #   include <sys/time.h>
 #   include <sys/resource.h>
 #endif /* BSD_TIME */
 
-# ifndef GC_H
-#   include "gc.h"
+# ifndef _GC_H
+#   include "../gc.h"
 # endif
 
 # ifndef GC_MARK_H
 #   include "../gc_mark.h"
 # endif
 
-# ifndef GCCONFIG_H
-#   include "gcconfig.h"
-# endif
-
 typedef GC_word word;
 typedef GC_signed_word signed_word;
 
@@ -60,6 +66,10 @@ typedef char * ptr_t;        /* A generic pointer to which we can add        */
                        /* Preferably identical to caddr_t, if it       */
                        /* exists.                                      */
                        
+# ifndef GCCONFIG_H
+#   include "gcconfig.h"
+# endif
+
 # ifndef HEADERS_H
 #   include "gc_hdrs.h"
 # endif
@@ -206,11 +216,10 @@ typedef char * ptr_t;     /* A generic pointer to which we can add        */
 #endif
 
 #if defined(GC_GCJ_SUPPORT) && ALIGNMENT < 8 && !defined(ALIGN_DOUBLE)
-   /* GCJ's Hashtable synchronization code requires 64-bit alignment.  */
+   /* GCJ's Hashtable synchronization code requires 64-bit alignment.  */
 #  define ALIGN_DOUBLE
 #endif
 
-
 /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
 # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
 #   define MERGE_SIZES
@@ -253,17 +262,6 @@ typedef char * ptr_t;      /* A generic pointer to which we can add        */
 /*                               */
 /*********************************/
 
-#ifdef SAVE_CALL_CHAIN
-
-/* Fill in the pc and argument information for up to NFRAMES of my     */
-/* callers.  Ignore my frame and my callers frame.                     */
-struct callinfo;
-void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES]));
-  
-void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
-
-#endif
-
 #ifdef NEED_CALLINFO
     struct callinfo {
        word ci_pc;     /* Caller, not callee, pc       */
@@ -277,6 +275,16 @@ void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
     };
 #endif
 
+#ifdef SAVE_CALL_CHAIN
+
+/* Fill in the pc and argument information for up to NFRAMES of my     */
+/* callers.  Ignore my frame and my callers frame.                     */
+void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES]));
+  
+void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
+
+#endif
+
 
 /*********************************/
 /*                               */
@@ -347,7 +355,8 @@ void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
 #   include <string.h>
 #   define BCOPY_EXISTS
 # endif
-# if defined(MACOSX)
+# if defined(DARWIN)
+#   include <string.h>
 #   define BCOPY_EXISTS
 # endif
 
@@ -360,68 +369,6 @@ void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
 #   define BZERO(x,n) bzero((char *)(x),(int)(n))
 # endif
 
-/* HBLKSIZE aligned allocation.  0 is taken to mean failure    */
-/* space is assumed to be cleared.                             */
-/* In the case os USE_MMAP, the argument must also be a        */
-/* physical page size.                                         */
-/* GET_MEM is currently not assumed to retrieve 0 filled space, */
-/* though we should perhaps take advantage of the case in which */
-/* does.                                                       */
-struct hblk;   /* See below.   */
-# ifdef PCR
-    char * real_malloc();
-#   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
-                                 + GC_page_size-1)
-# else
-#   ifdef OS2
-      void * os2_alloc(size_t bytes);
-#     define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
-                                   + GC_page_size) \
-                                    + GC_page_size-1)
-#   else
-#     if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
-        (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
-        (defined(SUNOS5) && !defined(USE_MMAP))
-#       define GET_MEM(bytes) HBLKPTR((size_t) \
-                                     calloc(1, (size_t)bytes + GC_page_size) \
-                                      + GC_page_size-1)
-#     else
-#      ifdef MSWIN32
-          extern ptr_t GC_win32_get_mem();
-#         define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
-#      else
-#        ifdef MACOS
-#          if defined(USE_TEMPORARY_MEMORY)
-               extern Ptr GC_MacTemporaryNewPtr(size_t size,
-                                                Boolean clearMemory);
-#               define GET_MEM(bytes) HBLKPTR( \
-                   GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
-                   + GC_page_size-1)
-#          else
-#                  define GET_MEM(bytes) HBLKPTR( \
-                       NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
-#          endif
-#        else
-#          ifdef MSWINCE
-             extern ptr_t GC_wince_get_mem();
-#            define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
-#          else
-#            if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
-               extern void *GC_amiga_get_mem(size_t size);
-               define GET_MEM(bytes) HBLKPTR((size_t) \
-                  GC_amiga_get_mem((size_t)bytes + GC_page_size) \
-                 + GC_page_size-1)
-#            else
-                extern ptr_t GC_unix_get_mem();
-#               define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
-#            endif
-#          endif
-#        endif
-#      endif
-#     endif
-#   endif
-# endif
-
 /* Delay any interrupts or signals that may abort this thread.  Data   */
 /* structures are in a consistent state outside this pair of calls.    */
 /* ANSI C allows both to be empty (though the standard isn't very      */
@@ -486,7 +433,7 @@ struct hblk;        /* See below.   */
 #   ifdef SMALL_CONFIG
 #      define ABORT(msg) abort();
 #   else
-       GC_API void GC_abort();
+       GC_API void GC_abort GC_PROTO((GC_CONST char * msg));
 #       define ABORT(msg) GC_abort(msg);
 #   endif
 # endif
@@ -504,11 +451,70 @@ extern GC_warn_proc GC_current_warn_proc;
 
 /* Get environment entry */
 #if !defined(NO_GETENV)
-#   define GETENV(name) getenv(name)
+#   if defined(EMPTY_GETENV_RESULTS)
+       /* Workaround for a reputed Wine bug.   */
+       static inline char * fixed_getenv(const char *name)
+       {
+         char * tmp = getenv(name);
+         if (tmp == 0 || strlen(tmp) == 0)
+           return 0;
+         return tmp;
+       }
+#       define GETENV(name) fixed_getenv(name)
+#   else
+#       define GETENV(name) getenv(name)
+#   endif
 #else
 #   define GETENV(name) 0
 #endif
 
+#if defined(DARWIN)
+#      if defined(POWERPC)
+#              if CPP_WORDSZ == 32
+#                define GC_THREAD_STATE_T ppc_thread_state_t
+#                define GC_MACH_THREAD_STATE PPC_THREAD_STATE
+#                define GC_MACH_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
+#                define GC_MACH_HEADER mach_header
+#                define GC_MACH_SECTION section
+#              else
+#                define GC_THREAD_STATE_T ppc_thread_state64_t
+#                define GC_MACH_THREAD_STATE PPC_THREAD_STATE64
+#                define GC_MACH_THREAD_STATE_COUNT PPC_THREAD_STATE64_COUNT
+#                define GC_MACH_HEADER mach_header_64
+#                define GC_MACH_SECTION section_64
+#              endif
+#      elif defined(I386) || defined(X86_64)
+#              if CPP_WORDSZ == 32
+#                define GC_THREAD_STATE_T x86_thread_state32_t
+#                define GC_MACH_THREAD_STATE x86_THREAD_STATE32
+#                define GC_MACH_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT
+#                define GC_MACH_HEADER mach_header
+#                define GC_MACH_SECTION section
+#              else
+#                define GC_THREAD_STATE_T x86_thread_state64_t
+#                define GC_MACH_THREAD_STATE x86_THREAD_STATE64
+#                define GC_MACH_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
+#                define GC_MACH_HEADER mach_header_64
+#                define GC_MACH_SECTION section_64
+#              endif
+#      else
+#              error define GC_THREAD_STATE_T
+#              define GC_MACH_THREAD_STATE MACHINE_THREAD_STATE
+#              define GC_MACH_THREAD_STATE_COUNT MACHINE_THREAD_STATE_COUNT
+#      endif
+/* Try to work out the right way to access thread state structure members.
+   The structure has changed its definition in different Darwin versions.
+   This now defaults to the (older) names without __, thus hopefully,
+   not breaking any existing Makefile.direct builds.  */
+#      if defined (HAS_PPC_THREAD_STATE___R0) \
+        || defined (HAS_PPC_THREAD_STATE64___R0) \
+        || defined (HAS_X86_THREAD_STATE32___EAX) \
+        || defined (HAS_X86_THREAD_STATE64___RAX)
+#        define THREAD_FLD(x) __ ## x
+#      else
+#        define THREAD_FLD(x) x
+#      endif
+#endif
 /*********************************/
 /*                               */
 /* Word-size-dependent defines   */
@@ -594,7 +600,7 @@ extern GC_warn_proc GC_current_warn_proc;
 
 #define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2)
 #define MAXOBJBYTES ((word)CPP_MAXOBJBYTES)
-#define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_HBLKSIZE/2)
+#define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_MAXOBJBYTES)
 #define MAXOBJSZ ((word)CPP_MAXOBJSZ)
                
 # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)
@@ -622,7 +628,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. */
@@ -646,9 +652,10 @@ extern GC_warn_proc GC_current_warn_proc;
  */
  
 # ifdef LARGE_CONFIG
-#   define LOG_PHT_ENTRIES  19  /* Collisions likely at 512K blocks,   */
-                               /* which is >= 2GB.  Each table takes   */
-                               /* 64KB.                                */
+#   define LOG_PHT_ENTRIES  20  /* Collisions likely at 1M blocks,     */
+                               /* which is >= 4GB.  Each table takes   */
+                               /* 128KB, some of which may never be    */
+                               /* touched.                             */
 # else
 #   ifdef SMALL_CONFIG
 #     define LOG_PHT_ENTRIES  14 /* Collisions are likely if heap grows        */
@@ -656,8 +663,12 @@ extern GC_warn_proc GC_current_warn_proc;
                                 /* Each hash table occupies 2K bytes.   */
 #   else /* default "medium" configuration */
 #     define LOG_PHT_ENTRIES  16 /* Collisions are likely if heap grows        */
-                                /* to more than 16K hblks >= 256MB.    */
+                                /* to more than 64K hblks >= 256MB.    */
                                 /* Each hash table occupies 8K bytes.  */
+                                /* Even for somewhat smaller heaps,    */
+                                /* say half that, collisions may be an */
+                                /* issue because we blacklist          */
+                                /* addresses outside the heap.         */
 #   endif
 # endif
 # define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES)
@@ -795,17 +806,9 @@ struct hblk {
 # ifdef LARGE_CONFIG
 #   define MAX_ROOT_SETS 4096
 # else
-#   ifdef PCR
-#     define MAX_ROOT_SETS 1024
-#   else
-#     if defined(MSWIN32) || defined(MSWINCE)
-#      define MAX_ROOT_SETS 1024
-           /* Under NT, we add only written pages, which can result    */
-           /* in many small root sets.                                 */
-#     else
-#       define MAX_ROOT_SETS 256
-#     endif
-#   endif
+    /* GCJ LOCAL: MAX_ROOT_SETS increased to permit more shared */
+    /* libraries to be loaded.                                  */ 
+#   define MAX_ROOT_SETS 1024
 # endif
 
 # define MAX_EXCLUSIONS (MAX_ROOT_SETS/4)
@@ -897,6 +900,10 @@ struct _GC_arrays {
   word _mem_freed;
        /* Number of explicitly deallocated words of memory     */
        /* since last collection.                               */
+  word _finalizer_mem_freed;
+       /* Words of memory explicitly deallocated while         */
+       /* finalizers were running.  Used to approximate mem.   */
+       /* explicitly deallocated by finalizers.                */
   ptr_t _scratch_end_ptr;
   ptr_t _scratch_last_end_ptr;
        /* Used by headers.c, and can easily appear to point to */
@@ -957,7 +964,7 @@ struct _GC_arrays {
                       /* OFFSET_TOO_BIG if the value j would be too    */
                       /* large to fit in the entry.  (Note that the    */
                       /* size of these entries matters, both for       */
-                      /* space consumption and for cache utilization.  */
+                      /* space consumption and for cache utilization.) */
 #   define OFFSET_TOO_BIG 0xfe
 #   define OBJ_INVALID 0xff
 #   define MAP_ENTRY(map, bytes) (map)[bytes]
@@ -973,11 +980,11 @@ struct _GC_arrays {
        char _valid_offsets[VALID_OFFSET_SZ];
                                /* GC_valid_offsets[i] == TRUE ==> i    */
                                /* is registered as a displacement.     */
-#      define OFFSET_VALID(displ) \
-         (GC_all_interior_pointers || GC_valid_offsets[displ])
        char _modws_valid_offsets[sizeof(word)];
                                /* GC_valid_offsets[i] ==>                */
                                /* GC_modws_valid_offsets[i%sizeof(word)] */
+#   define OFFSET_VALID(displ) \
+         (GC_all_interior_pointers || GC_valid_offsets[displ])
 # ifdef STUBBORN_ALLOC
     page_hash_table _changed_pages;
         /* Stubborn object pages that were changes since last call to  */
@@ -1005,7 +1012,7 @@ struct _GC_arrays {
 #   endif
 # else
 #   ifdef SMALL_CONFIG
-#     define MAX_HEAP_SECTS 128                /* Roughly 1GB                  */
+#     define MAX_HEAP_SECTS 128                /* Roughly 256MB (128*2048*1K)  */
 #   else
 #     define MAX_HEAP_SECTS 384                /* Roughly 3GB                  */
 #   endif
@@ -1067,6 +1074,7 @@ GC_API GC_FAR struct _GC_arrays GC_arrays;
 # define GC_words_finalized GC_arrays._words_finalized
 # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
 # define GC_mem_freed GC_arrays._mem_freed
+# define GC_finalizer_mem_freed GC_arrays._finalizer_mem_freed
 # define GC_scratch_end_ptr GC_arrays._scratch_end_ptr
 # define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr
 # define GC_mark_procs GC_arrays._mark_procs
@@ -1201,17 +1209,19 @@ extern struct hblk * GC_hblkfreelist[];
                                /* header structure associated with     */
                                /* block.                               */
 
-extern GC_bool GC_is_initialized;      /* GC_init() has been run.      */
-
 extern GC_bool GC_objects_are_marked;  /* There are marked objects in  */
                                        /* the heap.                    */
 
 #ifndef SMALL_CONFIG
   extern GC_bool GC_incremental;
                        /* Using incremental/generational collection. */
+# define TRUE_INCREMENTAL \
+       (GC_incremental && GC_time_limit != GC_TIME_UNLIMITED)
+       /* True incremental, not just generational, mode */
 #else
 # define GC_incremental FALSE
                        /* Hopefully allow optimizer to remove some code. */
+# define TRUE_INCREMENTAL FALSE
 #endif
 
 extern GC_bool GC_dirty_maintained;
@@ -1229,6 +1239,10 @@ extern long GC_large_alloc_warn_interval;
 extern long GC_large_alloc_warn_suppressed;
        /* Number of warnings suppressed so far.        */
 
+#ifdef THREADS
+  extern GC_bool GC_world_stopped;
+#endif
+
 /* Operations */
 # ifndef abs
 #   define abs(x)  ((x) < 0? (-(x)) : (x))
@@ -1403,6 +1417,11 @@ extern void (*GC_start_call_back) GC_PROTO((void));
 # else
   void GC_push_regs GC_PROTO((void));
 # endif
+# if defined(SPARC) || defined(IA64)
+  /* Cause all stacked registers to be saved in memory.  Return a      */
+  /* pointer to the top of the corresponding memory stack.             */
+  word GC_save_regs_in_stack GC_PROTO((void));
+# endif
                        /* Push register contents onto mark stack.      */
                        /* If NURSERY is defined, the default push      */
                        /* action can be overridden with GC_push_proc   */
@@ -1452,6 +1471,7 @@ 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));
+void GC_remove_roots_inner GC_PROTO((char * b, char * e));
 GC_bool GC_is_static_root GC_PROTO((ptr_t p));
                /* Is the address p in one of the registered static     */
                /* root sections?                                       */
@@ -1462,6 +1482,11 @@ GC_bool GC_is_tmp_root GC_PROTO((ptr_t p));
 # endif
 void GC_register_dynamic_libraries GC_PROTO((void));
                /* Add dynamic library data sections to the root set. */
+
+GC_bool GC_register_main_static_data GC_PROTO((void));
+               /* We need to register the main data segment.  Returns  */
+               /* TRUE unless this is done implicitly as part of       */
+               /* dynamic library registration.                        */
   
 /* Machine dependent startup routines */
 ptr_t GC_get_stack_base GC_PROTO((void));      /* Cold end of stack */
@@ -1619,6 +1644,8 @@ GC_bool GC_collect_or_expand GC_PROTO(( \
                                /* until the blocks are available or    */
                                /* until it fails by returning FALSE.   */
 
+extern GC_bool GC_is_initialized;      /* GC_init() has been run.      */
+
 #if defined(MSWIN32) || defined(MSWINCE)
   void GC_deinit GC_PROTO((void));
                                 /* Free any resources allocated by      */
@@ -1630,7 +1657,7 @@ void GC_collect_a_little_inner GC_PROTO((int n));
                                /* collection work, if appropriate.     */
                                /* A unit is an amount appropriate for  */
                                /* HBLKSIZE bytes of allocation.        */
-ptr_t GC_generic_malloc GC_PROTO((word lb, int k));
+/* ptr_t GC_generic_malloc GC_PROTO((word lb, int k)); */
                                /* Allocate an object of the given      */
                                /* kind.  By default, there are only    */
                                /* a few kinds: composite(pointerfree), */
@@ -1640,12 +1667,17 @@ ptr_t GC_generic_malloc GC_PROTO((word lb, int k));
                                /* internals to add more, e.g. to       */
                                /* communicate object layout info       */
                                /* to the collector.                    */
+                               /* The actual decl is in gc_mark.h.     */
 ptr_t GC_generic_malloc_ignore_off_page GC_PROTO((size_t b, int k));
                                /* As above, but pointers past the      */
                                /* first page of the resulting object   */
                                /* are ignored.                         */
 ptr_t GC_generic_malloc_inner GC_PROTO((word lb, int k));
                                /* Ditto, but I already hold lock, etc. */
+ptr_t GC_generic_malloc_words_small_inner GC_PROTO((word lw, int k));
+                               /* Analogous to the above, but assumes  */
+                               /* a small object size, and bypasses    */
+                               /* MERGE_SIZES mechanism.               */
 ptr_t GC_generic_malloc_words_small GC_PROTO((size_t lw, int k));
                                /* As above, but size in units of words */
                                /* Bypasses MERGE_SIZES.  Assumes       */
@@ -1660,6 +1692,8 @@ ptr_t GC_allocobj GC_PROTO((word sz, int kind));
                                /* Make the indicated                   */
                                /* free list nonempty, and return its   */
                                /* head.                                */
+
+void GC_free_inner(GC_PTR p);
   
 void GC_init_headers GC_PROTO((void));
 struct hblkhdr * GC_install_header GC_PROTO((struct hblk *h));
@@ -1689,6 +1723,12 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void));
                        /* Call *GC_finalizer_notifier if there are     */
                        /* finalizers to be run, and we haven't called  */
                        /* this procedure yet this GC cycle.            */
+
+GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
+GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
+                       /* Auxiliary fns to make finalization work      */
+                       /* correctly with displaced pointers introduced */
+                       /* by the debugging allocators.                 */
                        
 void GC_add_to_heap GC_PROTO((struct hblk *p, word bytes));
                        /* Add a HBLKSIZE aligned chunk to the heap.    */
@@ -1699,16 +1739,47 @@ void GC_print_obj GC_PROTO((ptr_t p));
                        /* description of the object to stderr.         */
 extern void (*GC_check_heap) GC_PROTO((void));
                        /* Check that all objects in the heap with      */
-                       /* debugging info are intact.  Print            */
-                       /* descriptions of any that are not.            */
+                       /* debugging info are intact.                   */
+                       /* Add any that are not to GC_smashed list.     */
+extern void (*GC_print_all_smashed) GC_PROTO((void));
+                       /* Print GC_smashed if it's not empty.          */
+                       /* Clear GC_smashed list.                       */
+extern void GC_print_all_errors GC_PROTO((void));
+                       /* Print smashed and leaked objects, if any.    */
+                       /* Clear the lists of such objects.             */
 extern void (*GC_print_heap_obj) GC_PROTO((ptr_t p));
                        /* If possible print s followed by a more       */
                        /* detailed description of the object           */
                        /* referred to by p.                            */
+#if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
+  void GC_print_address_map GC_PROTO((void));
+                       /* Print an address map of the process.         */
+#endif
 
+extern GC_bool GC_have_errors;  /* We saw a smashed or leaked object.  */
+                               /* Call error printing routine          */
+                               /* occasionally.                        */
 extern GC_bool GC_print_stats; /* Produce at least some logging output */
                                /* Set from environment variable.       */
 
+#ifndef NO_DEBUGGING
+  extern GC_bool GC_dump_regularly;  /* Generate regular debugging dumps. */
+# define COND_DUMP if (GC_dump_regularly) GC_dump();
+#else
+# define COND_DUMP
+#endif
+
+#ifdef KEEP_BACK_PTRS
+  extern long GC_backtraces;
+  void GC_generate_random_backtrace_no_gc(void);
+#endif
+
+extern GC_bool GC_print_back_height;
+
+#ifdef MAKE_BACK_GRAPH
+  void GC_print_back_graph_stats(void);
+#endif
+
 /* Macros used for collector internal allocation.      */
 /* These assume the collector lock is held.            */
 #ifdef DBG_HDRS_ALL
@@ -1780,6 +1851,7 @@ void GC_print_block_list GC_PROTO((void));
 void GC_print_hblkfreelist GC_PROTO((void));
 void GC_print_heap_sects GC_PROTO((void));
 void GC_print_static_roots GC_PROTO((void));
+void GC_print_finalization_stats GC_PROTO((void));
 void GC_dump GC_PROTO((void));
 
 #ifdef KEEP_BACK_PTRS
@@ -1861,6 +1933,16 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
 #      define GC_ASSERT(expr)
 # endif
 
+/* Check a compile time assertion at compile time.  The error  */
+/* message for failure is a bit baroque, but ...               */
+#if defined(mips) && !defined(__GNUC__)
+/* DOB: MIPSPro C gets an internal error taking the sizeof an array type. 
+   This code works correctly (ugliness is to avoid "unused var" warnings) */
+# define GC_STATIC_ASSERT(expr) do { if (0) { char j[(expr)? 1 : -1]; j[0]='\0'; j[0]=j[0]; } } while(0)
+#else
+# define GC_STATIC_ASSERT(expr) sizeof(char[(expr)? 1 : -1])
+#endif
+
 # if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
     /* We need additional synchronization facilities from the thread   */
     /* support.  We believe these are less performance critical                */
@@ -1906,7 +1988,7 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
   /* 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(GC_LINUX_THREADS)
+#   if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_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.            */
@@ -1916,7 +1998,11 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
 #      define SIG_SUSPEND SIGPWR
 #    endif
 #   else  /* !GC_LINUX_THREADS */
-#    define SIG_SUSPEND _SIGRTMIN + 6
+#     if defined(_SIGRTMIN)
+#       define SIG_SUSPEND _SIGRTMIN + 6
+#     else
+#       define SIG_SUSPEND SIGRTMIN + 6
+#     endif       
 #   endif
 #  endif /* !SIG_SUSPEND */