aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/include
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>1999-06-30 13:05:33 +0000
committerTom Tromey <tromey@gcc.gnu.org>1999-06-30 13:05:33 +0000
commit56ba54b4c0a72a7ee362d7f0c5b78976f4f88d96 (patch)
tree5807fec186c5db0ee8bcc27015b2079d04b2c27e /boehm-gc/include
parent2fa39a0ec6a238c23ce9c6df6fde18e9ea8625d4 (diff)
downloadgcc-56ba54b4c0a72a7ee362d7f0c5b78976f4f88d96.zip
gcc-56ba54b4c0a72a7ee362d7f0c5b78976f4f88d96.tar.gz
gcc-56ba54b4c0a72a7ee362d7f0c5b78976f4f88d96.tar.bz2
This commit was generated by cvs2svn to compensate for changes in r27853,
which included commits to RCS files with non-trunk default branches. From-SVN: r27854
Diffstat (limited to 'boehm-gc/include')
-rw-r--r--boehm-gc/include/gc.h51
-rw-r--r--boehm-gc/include/gc_cpp.h7
-rw-r--r--boehm-gc/include/private/gc_priv.h188
3 files changed, 208 insertions, 38 deletions
diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h
index 09c8ca8..ceabb02 100644
--- a/boehm-gc/include/gc.h
+++ b/boehm-gc/include/gc.h
@@ -36,11 +36,19 @@
#endif
#if defined(_MSC_VER) && defined(_DLL)
-#ifdef GC_BUILD
-#define GC_API __declspec(dllexport)
-#else
-#define GC_API __declspec(dllimport)
+# ifdef GC_BUILD
+# define GC_API __declspec(dllexport)
+# else
+# define GC_API __declspec(dllimport)
+# endif
#endif
+
+#if defined(__WATCOMC__) && defined(GC_DLL)
+# ifdef GC_BUILD
+# define GC_API extern __declspec(dllexport)
+# else
+# define GC_API extern __declspec(dllimport)
+# endif
#endif
#ifndef GC_API
@@ -126,7 +134,19 @@ GC_API GC_word GC_max_retries;
/* reporting out of memory after heap */
/* expansion fails. Initially 0. */
-
+
+GC_API char *GC_stackbottom; /* Cool end of user stack. */
+ /* May be set in the client prior to */
+ /* calling any GC_ routines. This */
+ /* avoids some overhead, and */
+ /* potentially some signals that can */
+ /* confuse debuggers. Otherwise the */
+ /* collector attempts to set it */
+ /* automatically. */
+ /* For multithreaded code, this is the */
+ /* cold end of the stack for the */
+ /* primordial thread. */
+
/* Public procedures */
/*
* general purpose allocation routines, with roughly malloc calling conv.
@@ -193,8 +213,8 @@ GC_API size_t GC_size GC_PROTO((GC_PTR object_addr));
/* If the argument is stubborn, the result will have changes enabled. */
/* It is an error to have changes enabled for the original object. */
/* Follows ANSI comventions for NULL old_object. */
-GC_API GC_PTR GC_realloc GC_PROTO((GC_PTR old_object,
- size_t new_size_in_bytes));
+GC_API GC_PTR GC_realloc
+ GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes));
/* Explicitly increase the heap size. */
/* Returns 0 on failure, 1 on success. */
@@ -248,6 +268,7 @@ GC_API void GC_gcollect GC_PROTO((void));
/* than normal pause times for incremental collection. However, */
/* aborted collections do no useful work; the next collection needs */
/* to start from the beginning. */
+/* Return 0 if the collection was aborted, 1 if it succeeded. */
typedef int (* GC_stop_func) GC_PROTO((void));
GC_API int GC_try_to_collect GC_PROTO((GC_stop_func stop_func));
@@ -604,6 +625,10 @@ GC_API void (*GC_is_valid_displacement_print_proc)
GC_API void (*GC_is_visible_print_proc)
GC_PROTO((GC_PTR p));
+#if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS)
+# define SOLARIS_THREADS
+#endif
+
#ifdef SOLARIS_THREADS
/* We need to intercept calls to many of the threads primitives, so */
/* that we can locate thread stacks and stop the world. */
@@ -660,7 +685,10 @@ GC_API void (*GC_is_visible_print_proc)
#endif /* IRIX_THREADS || LINUX_THREADS */
-#if defined(THREADS) && !defined(SRC_M3)
+# if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \
+ defined(IRIX_THREADS) || defined(LINUX_THREADS) || \
+ defined(IRIX_JDK_THREADS)
+ /* Any flavor of threads except SRC_M3. */
/* This returns a list of objects, linked through their first */
/* word. Its use can greatly reduce lock contention problems, since */
/* the allocation lock can be acquired and released many fewer times. */
@@ -691,6 +719,13 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 */
# endif
#endif
+#if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
+ || defined(_WIN32)
+ /* win32S may not free all resources on process exit. */
+ /* This explicitly deallocates the heap. */
+ GC_API void GC_win32_free_heap ();
+#endif
+
#ifdef __cplusplus
} /* end of extern "C" */
#endif
diff --git a/boehm-gc/include/gc_cpp.h b/boehm-gc/include/gc_cpp.h
index e2f456f..ad7df5d 100644
--- a/boehm-gc/include/gc_cpp.h
+++ b/boehm-gc/include/gc_cpp.h
@@ -133,7 +133,8 @@ uses explicit invocation.
#endif
#if ! defined( OPERATOR_NEW_ARRAY ) \
- && (__BORLANDC__ >= 0x450 || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6))
+ && (__BORLANDC__ >= 0x450 || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6) \
+ || __WATCOMC__ >= 1050)
# define OPERATOR_NEW_ARRAY
#endif
@@ -212,6 +213,8 @@ inline void* gc::operator new( size_t size ) {
inline void* gc::operator new( size_t size, GCPlacement gcp ) {
if (gcp == GC)
return GC_MALLOC( size );
+ else if (gcp == PointerFreeGC)
+ return GC_MALLOC_ATOMIC( size );
else
return GC_MALLOC_UNCOLLECTABLE( size );}
@@ -234,7 +237,7 @@ inline void gc::operator delete[]( void* obj ) {
inline gc_cleanup::~gc_cleanup() {
- GC_REGISTER_FINALIZER_IGNORE_SELF( this, 0, 0, 0, 0 );}
+ GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );}
inline void gc_cleanup::cleanup( void* obj, void* displ ) {
((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h
index 96ba1da..934075f 100644
--- a/boehm-gc/include/private/gc_priv.h
+++ b/boehm-gc/include/private/gc_priv.h
@@ -42,7 +42,7 @@ typedef GC_word word;
typedef GC_signed_word signed_word;
# ifndef CONFIG_H
-# include "config.h"
+# include "gcconfig.h"
# endif
# ifndef HEADERS_H
@@ -336,6 +336,9 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
/* 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. */
# ifdef PCR
char * real_malloc();
# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
@@ -434,7 +437,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
# ifdef LINUX_THREADS
# include <pthread.h>
# ifdef __i386__
- inline static GC_test_and_set(volatile unsigned int *addr) {
+ inline static int GC_test_and_set(volatile unsigned int *addr) {
int oldval;
/* Note: the "xchg" instruction does not need a "lock" prefix */
__asm__ __volatile__("xchgl %0, %1"
@@ -475,14 +478,15 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
}
# define EXIT_GC() GC_collecting = 0;
# endif /* LINUX_THREADS */
-# ifdef IRIX_THREADS
+# if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS)
# include <pthread.h>
# include <mutex.h>
-# if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
+# if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
+ || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
# define GC_test_and_set(addr, v) test_and_set(addr,v)
# else
-# define GC_test_and_set(addr, v) __test_and_set(addr,v)
+# define GC_test_and_set(addr, v) __test_and_set(addr,v)
# endif
extern unsigned long GC_allocate_lock;
/* This is not a mutex because mutexes that obey the (optional) */
@@ -501,10 +505,17 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
# define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
# else
# define LOCK() { if (GC_test_and_set(&GC_allocate_lock, 1)) GC_lock(); }
-# if __mips >= 3 && (defined (_ABIN32) || defined(_ABI64))
+# if __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) \
+ && defined(_COMPILER_VERSION) && _COMPILER_VERSION >= 700
# define UNLOCK() __lock_release(&GC_allocate_lock)
# else
-# define UNLOCK() GC_allocate_lock = 0
+ /* The function call in the following should prevent the */
+ /* compiler from moving assignments to below the UNLOCK. */
+ /* This is probably not necessary for ucode or gcc 2.8. */
+ /* It may be necessary for Ragnarok and future gcc */
+ /* versions. */
+# define UNLOCK() { GC_noop1(&GC_allocate_lock); \
+ *(volatile unsigned long *)(&GC_allocate_lock) = 0; }
# endif
# endif
extern GC_bool GC_collecting;
@@ -513,7 +524,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
GC_collecting = 1; \
}
# define EXIT_GC() GC_collecting = 0;
-# endif /* IRIX_THREADS */
+# endif /* IRIX_THREADS || IRIX_JDK_THREADS */
# ifdef WIN32_THREADS
# include <windows.h>
GC_API CRITICAL_SECTION GC_allocate_ml;
@@ -567,7 +578,7 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
# if defined(SRC_M3) || defined(AMIGA) || defined(SOLARIS_THREADS) \
|| defined(MSWIN32) || defined(MACOS) || defined(DJGPP) \
|| defined(NO_SIGNALS) || defined(IRIX_THREADS) \
- || defined(LINUX_THREADS)
+ || defined(IRIX_JDK_THREADS) || defined(LINUX_THREADS)
/* Also useful for debugging. */
/* Should probably use thr_sigsetmask for SOLARIS_THREADS. */
# define DISABLE_SIGNALS()
@@ -595,7 +606,8 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
PCR_waitForever);
# else
# if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
- || defined(IRIX_THREADS) || defined(LINUX_THREADS)
+ || defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+ || defined(IRIX_JDK_THREADS)
void GC_stop_world();
void GC_start_world();
# define STOP_WORLD() GC_stop_world()
@@ -864,7 +876,69 @@ struct hblk {
/* Object free list link */
# define obj_link(p) (*(ptr_t *)(p))
-/* lists of all heap blocks and free lists */
+/* The type of mark procedures. This really belongs in gc_mark.h. */
+/* But we put it here, so that we can avoid scanning the mark proc */
+/* table. */
+typedef struct ms_entry * (*mark_proc)(/* word * addr, mark_stack_ptr,
+ mark_stack_limit, env */);
+# define LOG_MAX_MARK_PROCS 6
+# define MAX_MARK_PROCS (1 << LOG_MAX_MARK_PROCS)
+
+/* Root sets. Logically private to mark_rts.c. But we don't want the */
+/* tables scanned, so we put them here. */
+/* MAX_ROOT_SETS is the maximum number of ranges that can be */
+/* registered as static roots. */
+# ifdef LARGE_CONFIG
+# define MAX_ROOT_SETS 4096
+# else
+# ifdef PCR
+# define MAX_ROOT_SETS 1024
+# else
+# ifdef MSWIN32
+# define MAX_ROOT_SETS 512
+ /* Under NT, we add only written pages, which can result */
+ /* in many small root sets. */
+# else
+# define MAX_ROOT_SETS 64
+# endif
+# endif
+# endif
+
+# define MAX_EXCLUSIONS (MAX_ROOT_SETS/4)
+/* Maximum number of segments that can be excluded from root sets. */
+
+/*
+ * Data structure for excluded static roots.
+ */
+struct exclusion {
+ ptr_t e_start;
+ ptr_t e_end;
+};
+
+/* Data structure for list of root sets. */
+/* We keep a hash table, so that we can filter out duplicate additions. */
+/* Under Win32, we need to do a better job of filtering overlaps, so */
+/* we resort to sequential search, and pay the price. */
+struct roots {
+ ptr_t r_start;
+ ptr_t r_end;
+# ifndef MSWIN32
+ struct roots * r_next;
+# endif
+ GC_bool r_tmp;
+ /* Delete before registering new dynamic libraries */
+};
+
+#ifndef MSWIN32
+ /* Size of hash table index to roots. */
+# define LOG_RT_SIZE 6
+# define RT_SIZE (1 << LOG_RT_SIZE) /* Power of 2, may be != MAX_ROOT_SETS */
+#endif
+
+/* Lists of all heap blocks and free lists */
+/* as well as other random data structures */
+/* that should not be scanned by the */
+/* collector. */
/* These are grouped together in a struct */
/* so that they can be easily skipped by the */
/* GC_mark routine. */
@@ -904,7 +978,10 @@ struct _GC_arrays {
word _mem_freed;
/* Number of explicitly deallocated words of memory */
/* since last collection. */
-
+ mark_proc _mark_procs[MAX_MARK_PROCS];
+ /* Table of user-defined mark procedures. There is */
+ /* a small number of these, which can be referenced */
+ /* by DS_PROC mark descriptors. See gc_mark.h. */
ptr_t _objfreelist[MAXOBJSZ+1];
/* free list for objects */
ptr_t _aobjfreelist[MAXOBJSZ+1];
@@ -986,17 +1063,24 @@ struct _GC_arrays {
/* GC_modws_valid_offsets[i%sizeof(word)] */
# endif
# ifdef STUBBORN_ALLOC
- page_hash_table _changed_pages;
+ page_hash_table _changed_pages;
/* Stubborn object pages that were changes since last call to */
/* GC_read_changed. */
- page_hash_table _prev_changed_pages;
+ page_hash_table _prev_changed_pages;
/* Stubborn object pages that were changes before last call to */
/* GC_read_changed. */
# endif
# if defined(PROC_VDB) || defined(MPROTECT_VDB)
- page_hash_table _grungy_pages; /* Pages that were dirty at last */
+ page_hash_table _grungy_pages; /* Pages that were dirty at last */
/* GC_read_dirty. */
# endif
+# ifdef MPROTECT_VDB
+ VOLATILE page_hash_table _dirty_pages;
+ /* Pages dirtied since last GC_read_dirty. */
+# endif
+# ifdef PROC_VDB
+ page_hash_table _written_pages; /* Pages ever dirtied */
+# endif
# ifdef LARGE_CONFIG
# if CPP_WORDSZ > 32
# define MAX_HEAP_SECTS 4096 /* overflows at roughly 64 GB */
@@ -1013,6 +1097,11 @@ struct _GC_arrays {
ptr_t _heap_bases[MAX_HEAP_SECTS];
/* Start address of memory regions obtained from kernel. */
# endif
+ struct roots _static_roots[MAX_ROOT_SETS];
+# ifndef MSWIN32
+ struct roots * _root_index[RT_SIZE];
+# endif
+ struct exclusion _excl_table[MAX_EXCLUSIONS];
/* Block header index; see gc_headers.h */
bottom_index * _all_nils;
bottom_index * _top_index [TOP_SZ];
@@ -1049,6 +1138,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_mark_procs GC_arrays._mark_procs
# define GC_heapsize GC_arrays._heapsize
# define GC_max_heapsize GC_arrays._max_heapsize
# define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc
@@ -1057,11 +1147,20 @@ GC_API GC_FAR struct _GC_arrays GC_arrays;
# ifdef MSWIN32
# define GC_heap_bases GC_arrays._heap_bases
# endif
+# define GC_static_roots GC_arrays._static_roots
+# define GC_root_index GC_arrays._root_index
+# define GC_excl_table GC_arrays._excl_table
# define GC_all_nils GC_arrays._all_nils
# define GC_top_index GC_arrays._top_index
# if defined(PROC_VDB) || defined(MPROTECT_VDB)
# define GC_grungy_pages GC_arrays._grungy_pages
# endif
+# ifdef MPROTECT_VDB
+# define GC_dirty_pages GC_arrays._dirty_pages
+# endif
+# ifdef PROC_VDB
+# define GC_written_pages GC_arrays._written_pages
+# endif
# ifdef GATHERSTATS
# define GC_composite_in_use GC_arrays._composite_in_use
# define GC_atomic_in_use GC_arrays._atomic_in_use
@@ -1073,11 +1172,9 @@ GC_API GC_FAR struct _GC_arrays GC_arrays;
# define beginGC_arrays ((ptr_t)(&GC_arrays))
# define endGC_arrays (((ptr_t)(&GC_arrays)) + (sizeof GC_arrays))
-GC_API word GC_fo_entries;
-
+/* Object kinds: */
# define MAXOBJKINDS 16
-/* Object kinds: */
extern struct obj_kind {
ptr_t *ok_freelist; /* Array of free listheaders for this kind of object */
/* Point either to GC_arrays or to storage allocated */
@@ -1091,8 +1188,14 @@ extern struct obj_kind {
/* Add object size in bytes to descriptor */
/* template to obtain descriptor. Otherwise */
/* template is used as is. */
- GC_bool ok_init; /* Clear objects before putting them on the free list. */
+ GC_bool ok_init; /* Clear objects before putting them on the free list. */
} GC_obj_kinds[MAXOBJKINDS];
+
+# define endGC_obj_kinds (((ptr_t)(&GC_obj_kinds)) + (sizeof GC_obj_kinds))
+
+# define end_gc_area ((ptr_t)endGC_arrays == (ptr_t)(&GC_obj_kinds) ? \
+ endGC_obj_kinds : endGC_arrays)
+
/* Predefined kinds: */
# define PTRFREE 0
# define NORMAL 1
@@ -1108,6 +1211,8 @@ extern struct obj_kind {
extern int GC_n_kinds;
+GC_API word GC_fo_entries;
+
extern word GC_n_heap_sects; /* Number of separately added heap */
/* sections. */
@@ -1142,17 +1247,19 @@ 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. */
-extern GC_bool GC_incremental; /* Using incremental/generational collection. */
+#ifndef SMALL_CONFIG
+ extern GC_bool GC_incremental;
+ /* Using incremental/generational collection. */
+#else
+# define GC_incremental TRUE
+ /* Hopefully allow optimizer to remove some code. */
+#endif
extern GC_bool GC_dirty_maintained;
/* Dirty bits are being maintained, */
/* either for incremental collection, */
/* or to limit the root set. */
-# ifndef PCR
- extern ptr_t GC_stackbottom; /* Cool end of user stack */
-# endif
-
extern word GC_root_size; /* Total size of registered root sections */
extern GC_bool GC_debugging_started; /* GC_debug_malloc has been called. */
@@ -1216,7 +1323,8 @@ void GC_mark_from_mark_stack(); /* Mark from everything on the mark stack. */
/* Return after about one pages worth of */
/* work. */
GC_bool GC_mark_stack_empty();
-GC_bool GC_mark_some(); /* Perform about one pages worth of marking */
+GC_bool GC_mark_some(/* cold_gc_frame */);
+ /* Perform about one pages worth of marking */
/* work of whatever kind is needed. Returns */
/* quickly if no collection is in progress. */
/* Return TRUE if mark phase finished. */
@@ -1238,7 +1346,31 @@ void GC_push_dirty(/*b,t*/); /* Push all possibly changed */
/* on the third arg. */
void GC_push_all_stack(/*b,t*/); /* As above, but consider */
/* interior pointers as valid */
-void GC_push_roots(/* GC_bool all */); /* Push all or dirty roots. */
+void GC_push_all_eager(/*b,t*/); /* Same as GC_push_all_stack, but */
+ /* ensures that stack is scanned */
+ /* immediately, not just scheduled */
+ /* for scanning. */
+#ifndef THREADS
+ void GC_push_all_stack_partially_eager(/* bottom, top, cold_gc_frame */);
+ /* Similar to GC_push_all_eager, but only the */
+ /* part hotter than cold_gc_frame is scanned */
+ /* immediately. Needed to endure that callee- */
+ /* save registers are not missed. */
+#else
+ /* In the threads case, we push part of the current thread stack */
+ /* with GC_push_all_eager when we push the registers. This gets the */
+ /* callee-save registers that may disappear. The remainder of the */
+ /* stacks are scheduled for scanning in *GC_push_other_roots, which */
+ /* is thread-package-specific. */
+#endif
+void GC_push_current_stack(/* ptr_t cold_gc_frame */);
+ /* Push enough of the current stack eagerly to */
+ /* ensure that callee-save registers saved in */
+ /* GC frames are scanned. */
+ /* In the non-threads case, schedule entire */
+ /* stack for scanning. */
+void GC_push_roots(/* GC_bool all, ptr_t cold_gc_frame */);
+ /* Push all or dirty roots. */
extern void (*GC_push_other_roots)();
/* Push system or application specific roots */
/* onto the mark stack. In some environments */
@@ -1403,7 +1535,7 @@ GC_bool GC_collect_or_expand(/* needed_blocks */);
/* blocks available. Should be called */
/* until the blocks are available or */
/* until it fails by returning FALSE. */
-void GC_init(); /* Initialize collector. */
+GC_API void GC_init(); /* Initialize collector. */
void GC_collect_a_little_inner(/* int n */);
/* Do n units worth of garbage */
/* collection work, if appropriate. */
@@ -1491,7 +1623,7 @@ void GC_write_hint(/* struct hblk * h */);
void GC_dirty_init();
/* Slow/general mark bit manipulation: */
-GC_bool GC_is_marked();
+GC_API GC_bool GC_is_marked();
void GC_clear_mark_bit();
void GC_set_mark_bit();