=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/gc/include/gc.h,v retrieving revision 1.3 retrieving revision 1.6 diff -u -p -r1.3 -r1.6 --- OpenXM_contrib2/asir2000/gc/include/gc.h 2001/04/20 07:39:25 1.3 +++ OpenXM_contrib2/asir2000/gc/include/gc.h 2003/06/24 05:11:40 1.6 @@ -30,89 +30,8 @@ # define _GC_H -#if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) -# define SOLARIS_THREADS -#endif +# include "gc_config_macros.h" -/* - * Some tests for old macros. These violate our namespace rules and will - * disappear shortly. - */ -#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) -# define GC_SOLARIS_THREADS -#endif -#if defined(_SOLARIS_PTHREADS) -# define GC_SOLARIS_PTHREADS -#endif -#if defined(IRIX_THREADS) -# define GC_IRIX_THREADS -#endif -#if defined(HPUX_THREADS) -# define GC_HPUX_THREADS -#endif -#if defined(OSF1_THREADS) -# define GC_OSF1_THREADS -#endif -#if defined(LINUX_THREADS) -# define GC_LINUX_THREADS -#endif -#if defined(WIN32_THREADS) -# define GC_WIN32_THREADS -#endif -#if defined(USE_LD_WRAP) -# define GC_USE_LD_WRAP -#endif - -#if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \ - || defined(GC_SOLARIS_PTHREADS) \ - || defined(GC_HPUX_THREADS) \ - || defined(GC_LINUX_THREADS)) -# define _REENTRANT - /* Better late than never. This fails if system headers that */ - /* depend on this were previously included. */ -#endif - -# define __GC -# include -# ifdef _WIN32_WCE -/* Yet more kluges for WinCE */ -# include /* size_t is defined here */ - 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) -# else -# define GC_API __declspec(dllimport) -# endif -#endif - -#if defined(_MSC_VER) && (defined(_DLL) && !defined(NOT_GC_DLL) \ - || defined(GC_DLL)) -# ifdef GC_BUILD -# define GC_API extern __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 -#define GC_API extern -#endif - # if defined(__STDC__) || defined(__cplusplus) # define GC_PROTO(args) args typedef void * GC_PTR; @@ -151,7 +70,7 @@ GC_API int GC_parallel; /* GC is parallelized for perf /* Env variable GC_NPROC is set to > 1, or */ /* GC_NPROC is not set and this is an MP. */ /* If GC_parallel is set, incremental */ - /* collection is aonly partially functional, */ + /* collection is only partially functional, */ /* and may not be desirable. */ @@ -212,8 +131,14 @@ GC_API void (* GC_finalizer_notifier)(); /* thread, which will call GC_invoke_finalizers */ /* in response. */ -GC_API int GC_dont_gc; /* Dont collect unless explicitly requested, e.g. */ - /* because it's not safe. */ +GC_API int GC_dont_gc; /* != 0 ==> Dont collect. In versions 7.2a1+, */ + /* this overrides explicit GC_gcollect() calls. */ + /* Used as a counter, so that nested enabling */ + /* and disabling work correctly. Should */ + /* normally be updated with GC_enable() and */ + /* GC_disable() calls. */ + /* Direct assignment to GC_dont_gc is */ + /* deprecated. */ GC_API int GC_dont_expand; /* Dont expand heap unless explicitly requested */ @@ -293,7 +218,29 @@ GC_API int GC_dont_precollect; /* Don't collect as pa /* Interferes with blacklisting. */ /* Wizards only. */ +GC_API unsigned long GC_time_limit; + /* If incremental collection is enabled, */ + /* We try to terminate collections */ + /* after this many milliseconds. Not a */ + /* hard time bound. Setting this to */ + /* GC_TIME_UNLIMITED will essentially */ + /* disable incremental collection while */ + /* leaving generational collection */ + /* enabled. */ +# define GC_TIME_UNLIMITED 999999 + /* Setting GC_time_limit to this value */ + /* will disable the "pause time exceeded"*/ + /* tests. */ + /* Public procedures */ + +/* Initialize the collector. This is only required when using thread-local + * allocation, since unlike the regular allocation routines, GC_local_malloc + * is not self-initializing. If you use GC_local_malloc you should arrange + * to call this somehow (e.g. from a constructor) before doing any allocation. + */ +GC_API void GC_init GC_PROTO((void)); + /* * general purpose allocation routines, with roughly malloc calling conv. * The atomic versions promise that no relevant pointers are contained @@ -347,6 +294,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)); @@ -390,17 +341,21 @@ GC_API void GC_clear_roots GC_PROTO((void)); GC_API void GC_add_roots GC_PROTO((char * low_address, char * high_address_plus_1)); +/* Remove a root segment. Wizards only. */ +GC_API void GC_remove_roots GC_PROTO((char * low_address, + char * high_address_plus_1)); + /* Add a displacement to the set of those considered valid by the */ /* collector. GC_register_displacement(n) means that if p was returned */ /* by GC_malloc, then (char *)p + n will be considered to be a valid */ -/* pointer to n. N must be small and less than the size of p. */ +/* pointer to p. N must be small and less than the size of p. */ /* (All pointers to the interior of objects from the stack are */ /* considered valid in any case. This applies to heap objects and */ /* static data.) */ /* Preferably, this should be called before any other GC procedures. */ /* Calling it later adds to the probability of excess memory */ /* retention. */ -/* This is a no-op if the collector was compiled with recognition of */ +/* This is a no-op if the collector has recognition of */ /* arbitrary interior pointers enabled, which is now the default. */ GC_API void GC_register_displacement GC_PROTO((GC_word n)); @@ -435,9 +390,18 @@ GC_API size_t GC_get_free_bytes GC_PROTO((void)); GC_API size_t GC_get_bytes_since_gc GC_PROTO((void)); /* Return the total number of bytes allocated in this process. */ -/* Never decreases. */ +/* Never decreases, except due to wrapping. */ GC_API size_t GC_get_total_bytes GC_PROTO((void)); +/* Disable garbage collection. Even GC_gcollect calls will be */ +/* ineffective. */ +GC_API void GC_disable GC_PROTO((void)); + +/* Reenable garbage collection. GC_diable() and GC_enable() calls */ +/* nest. Garbage collection is enabled if the number of calls to both */ +/* both functions is equal. */ +GC_API void GC_enable GC_PROTO((void)); + /* Enable incremental/generational collection. */ /* Not advisable unless dirty bits are */ /* available or most heap objects are */ @@ -445,9 +409,23 @@ GC_API size_t GC_get_total_bytes GC_PROTO((void)); /* Don't use in leak finding mode. */ /* Ignored if GC_dont_gc is true. */ /* Only the generational piece of this is */ -/* functional if GC_parallel is TRUE. */ +/* functional if GC_parallel is TRUE */ +/* or if GC_time_limit is GC_TIME_UNLIMITED. */ +/* Causes GC_local_gcj_malloc() to revert to */ +/* locked allocation. Must be called */ +/* before any GC_local_gcj_malloc() calls. */ GC_API void GC_enable_incremental GC_PROTO((void)); +/* Does incremental mode write-protect pages? Returns zero or */ +/* more of the following, or'ed together: */ +#define GC_PROTECTS_POINTER_HEAP 1 /* May protect non-atomic objs. */ +#define GC_PROTECTS_PTRFREE_HEAP 2 +#define GC_PROTECTS_STATIC_DATA 4 /* Curently never. */ +#define GC_PROTECTS_STACK 8 /* Probably impractical. */ + +#define GC_PROTECTS_NONE 0 +GC_API int GC_incremental_protection_needs GC_PROTO((void)); + /* Perform some garbage collection work, if appropriate. */ /* Return 0 if there is no more work to be done. */ /* Typically performs an amount of work corresponding roughly */ @@ -479,6 +457,42 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROT # define GC_RETURN_ADDR (GC_word)__return_address #endif +#ifdef __linux__ +# include +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ + && !defined(__ia64__) +# define GC_HAVE_BUILTIN_BACKTRACE +# define GC_CAN_SAVE_CALL_STACKS +# endif +# if defined(__i386__) || defined(__x86_64__) +# define GC_CAN_SAVE_CALL_STACKS +# endif +#endif + +#if defined(__sparc__) +# define GC_CAN_SAVE_CALL_STACKS +#endif + +/* If we're on an a platform on which we can't save call stacks, but */ +/* gcc is normally used, we go ahead and define GC_ADD_CALLER. */ +/* We make this decision independent of whether gcc is actually being */ +/* used, in order to keep the interface consistent, and allow mixing */ +/* of compilers. */ +/* This may also be desirable if it is possible but expensive to */ +/* retrieve the call chain. */ +#if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(__FreeBSD__)) & !defined(GC_CAN_SAVE_CALL_STACKS) +# define GC_ADD_CALLER +# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) + /* gcc knows how to retrieve return address, but we don't know */ + /* how to generate call stacks. */ +# define GC_RETURN_ADDR (GC_word)__builtin_return_address(0) +# else + /* Just pass 0 for gcc compatibility. */ +# define GC_RETURN_ADDR 0 +# endif +#endif + #ifdef GC_ADD_CALLER # define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__ # define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * s, int i @@ -497,18 +511,42 @@ GC_API GC_PTR GC_debug_malloc_uncollectable GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); GC_API GC_PTR GC_debug_malloc_stubborn GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); +GC_API GC_PTR GC_debug_malloc_ignore_off_page + GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); +GC_API GC_PTR GC_debug_malloc_atomic_ignore_off_page + GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); GC_API void GC_debug_free GC_PROTO((GC_PTR object_addr)); GC_API GC_PTR GC_debug_realloc GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes, GC_EXTRA_PARAMS)); - GC_API void GC_debug_change_stubborn GC_PROTO((GC_PTR)); GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_PTR)); + +/* Routines that allocate objects with debug information (like the */ +/* above), but just fill in dummy file and line number information. */ +/* Thus they can serve as drop-in malloc/realloc replacements. This */ +/* can be useful for two reasons: */ +/* 1) It allows the collector to be built with DBG_HDRS_ALL defined */ +/* even if some allocation calls come from 3rd party libraries */ +/* that can't be recompiled. */ +/* 2) On some platforms, the file and line information is redundant, */ +/* since it can be reconstructed from a stack trace. On such */ +/* platforms it may be more convenient not to recompile, e.g. for */ +/* leak detection. This can be accomplished by instructing the */ +/* linker to replace malloc/realloc with these. */ +GC_API GC_PTR GC_debug_malloc_replacement GC_PROTO((size_t size_in_bytes)); +GC_API GC_PTR GC_debug_realloc_replacement + GC_PROTO((GC_PTR object_addr, size_t size_in_bytes)); + # ifdef GC_DEBUG # define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS) # define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS) -# define GC_MALLOC_UNCOLLECTABLE(sz) GC_debug_malloc_uncollectable(sz, \ - GC_EXTRAS) +# define GC_MALLOC_UNCOLLECTABLE(sz) \ + GC_debug_malloc_uncollectable(sz, GC_EXTRAS) +# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \ + GC_debug_malloc_ignore_off_page(sz, GC_EXTRAS) +# define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \ + GC_debug_malloc_atomic_ignore_off_page(sz, GC_EXTRAS) # define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS) # define GC_FREE(p) GC_debug_free(p) # define GC_REGISTER_FINALIZER(p, f, d, of, od) \ @@ -527,6 +565,10 @@ GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_ # define GC_MALLOC(sz) GC_malloc(sz) # define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz) # define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz) +# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \ + GC_malloc_ignore_off_page(sz) +# define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \ + GC_malloc_atomic_ignore_off_page(sz) # define GC_REALLOC(old, sz) GC_realloc(old, sz) # define GC_FREE(p) GC_free(p) # define GC_REGISTER_FINALIZER(p, f, d, of, od) \ @@ -605,7 +647,8 @@ GC_API void GC_debug_register_finalizer /* itself. There is a stylistic argument that this is wrong, */ /* but it's unavoidable for C++, since the compiler may */ /* silently introduce these. It's also benign in that specific */ -/* case. */ +/* case. And it helps if finalizable objects are split to */ +/* avoid cycles. */ /* Note that cd will still be viewed as accessible, even if it */ /* refers to the object itself. */ GC_API void GC_register_finalizer_ignore_self @@ -678,11 +721,6 @@ GC_API int GC_unregister_disappearing_link GC_PROTO((G /* Undoes a registration by either of the above two */ /* routines. */ -/* Auxiliary fns to make finalization work correctly with displaced */ -/* pointers introduced by the debugging allocators. */ -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)); - /* Returns !=0 if GC_invoke_finalizers has something to do. */ GC_API int GC_should_invoke_finalizers GC_PROTO((void)); @@ -699,9 +737,13 @@ GC_API int GC_invoke_finalizers GC_PROTO((void)); typedef void (*GC_warn_proc) GC_PROTO((char *msg, GC_word arg)); GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p)); /* Returns old warning procedure. */ + +GC_API GC_word GC_set_free_space_divisor GC_PROTO((GC_word value)); + /* Set free_space_divisor. See above for definition. */ + /* Returns old value. */ /* 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. */ @@ -814,16 +856,12 @@ GC_API void (*GC_is_visible_print_proc) /* thread library calls. We do that here by macro defining them. */ #if !defined(GC_USE_LD_WRAP) && \ - (defined(GC_LINUX_THREADS) || defined(GC_HPUX_THREADS) || \ - defined(GC_IRIX_THREADS) || defined(GC_SOLARIS_PTHREADS) || \ - defined(GC_SOLARIS_THREADS) || defined(GC_OSF1_THREADS)) + (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)) # include "gc_pthread_redirects.h" #endif # if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ - defined(GC_SOLARIS_PTHREADS) || defined(GC_WIN32_THREADS) || \ - defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \ - defined(GC_HPUX_THREADS) + defined(GC_PTHREADS) || defined(GC_WIN32_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 */ @@ -838,10 +876,23 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 * #endif /* THREADS && !SRC_M3 */ -#if defined(WIN32_THREADS) && defined(_WIN32_WCE) +#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) # include /* + * All threads must be created using GC_CreateThread, so that they will be + * recorded in the thread table. For backwards compatibility, this is not + * technically true if the GC is built as a dynamic library, since it can + * and does then use DllMain to keep track of thread creations. But new code + * should be built to call GC_CreateThread. + */ + GC_API HANDLE GC_CreateThread( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); + +# if defined(_WIN32_WCE) + /* * win32_threads.c implements the real WinMain, which will start a new thread * to call GC_WinMain after initializing the garbage collector. */ @@ -851,22 +902,14 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 * LPWSTR lpCmdLine, int nCmdShow ); - /* - * All threads must be created using GC_CreateThread, so that they will be - * recorded in the thread table. - */ - HANDLE WINAPI GC_CreateThread( - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); +# ifndef GC_BUILD +# define WinMain GC_WinMain +# define CreateThread GC_CreateThread +# endif +# endif /* defined(_WIN32_WCE) */ -# ifndef GC_BUILD -# define WinMain GC_WinMain -# define CreateThread GC_CreateThread -# endif +#endif /* defined(GC_WIN32_THREADS) && !cygwin */ -#endif - /* * If you are planning on putting * the collector in a SunOS 5 dynamic library, you need to call GC_INIT() @@ -877,13 +920,18 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 * # define GC_INIT() { extern end, etext; \ GC_noop(&end, &etext); } #else -# if defined(__CYGWIN32__) && defined(GC_USE_DLL) +# if defined(__CYGWIN32__) && defined(GC_DLL) || defined (_AIX) /* - * Similarly gnu-win32 DLLs need explicit initialization + * Similarly gnu-win32 DLLs need explicit initialization from + * the main program, as does AIX. */ # define GC_INIT() { GC_add_roots(DATASTART, DATAEND); } # else +# if defined(__APPLE__) && defined(__MACH__) +# define GC_INIT() { GC_init(); } +# else # define GC_INIT() +# endif # endif #endif