# 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
/* */
/*********************************/
-#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 */
};
#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
+
/*********************************/
/* */
/* 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 */
#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)
# 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. */
# define LOG_PHT_ENTRIES 16 /* Collisions are likely if heap grows */
/* 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)
# 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)
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 */
# 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
# 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 */
/* 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), */
/* 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 */
# 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