# define _GC_H
-/*
- * Some tests for old macros. These violate our namespace rules and will
- * disappear shortly. Use the GC_ names.
+/*
+ * As this header includes gc_config.h, preprocessor conflicts can occur with
+ * clients that include their own autoconf headers. The following #undef's
+ * work around some likely conflicts.
*/
-#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
-
-#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
-# define GC_SOLARIS_THREADS
-#endif
-
-# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
- defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
- defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
-# define GC_PTHREADS
+# ifdef PACKAGE_NAME
+# undef PACKAGE_NAME
# endif
-
-# define __GC
-# include <stddef.h>
-# ifdef _WIN32_WCE
-/* Yet more kluges for WinCE */
-# include <stdlib.h> /* size_t is defined here */
- typedef long ptrdiff_t; /* ptrdiff_t is not defined */
+# ifdef PACKAGE_BUGREPORT
+# undef PACKAGE_BUGREPORT
# endif
-
-#if defined(__MINGW32__) && defined(GC_WIN32_THREADS)
-# ifdef GC_BUILD
-# define GC_API __declspec(dllexport)
-# else
-# define GC_API __declspec(dllimport)
+# ifdef PACKAGE_STRING
+# undef PACKAGE_STRING
# endif
-#endif
-
-#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
-# define GC_API __declspec(dllimport)
+# ifdef PACKAGE_TARNAME
+# undef PACKAGE_TARNAME
# endif
-#endif
-
-#if defined(__WATCOMC__) && defined(GC_DLL)
-# ifdef GC_BUILD
-# define GC_API extern __declspec(dllexport)
-# else
-# define GC_API extern __declspec(dllimport)
+# ifdef PACKAGE_VERSION
+# undef PACKAGE_VERSION
# endif
-#endif
-#ifndef GC_API
-#define GC_API extern
-#endif
+# include <gc_config.h>
+# include "gc_config_macros.h"
# if defined(__STDC__) || defined(__cplusplus)
# define GC_PROTO(args) args
/* even semi-portably. The following is probably no better/worse */
/* than almost anything else. */
/* The ANSI standard suggests that size_t and ptr_diff_t might be */
-/* better choices. But those appear to have incorrect definitions */
-/* on may systems. Notably "typedef int size_t" seems to be both */
-/* frequent and WRONG. */
-typedef unsigned long GC_word;
-typedef long GC_signed_word;
+/* better choices. But those had incorrect definitions on some older */
+/* systems. Notably "typedef int size_t" is WRONG. */
+#ifndef _WIN64
+ typedef unsigned long GC_word;
+ typedef long GC_signed_word;
+#else
+ /* Win64 isn't really supported yet, but this is the first step. And */
+ /* it might cause error messages to show up in more plausible places. */
+ /* This needs basetsd.h, which is included by windows.h. */
+ typedef ULONG_PTR GC_word;
+ typedef LONG_PTR GC_word;
+#endif
/* Public read-only variables */
/* 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. */
/* 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 6.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 */
*/
GC_API void GC_init GC_PROTO((void));
+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.
+ * For win32 threads, it needs to be called explicitly.
+ */
+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
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));
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_disable() 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 */
/* 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 */
# define GC_RETURN_ADDR (GC_word)__return_address
#endif
+#ifdef __linux__
+# include <features.h>
+# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
+ && !defined(__ia64__)
+# ifndef GC_HAVE_BUILTIN_BACKTRACE
+# define GC_HAVE_BUILTIN_BACKTRACE
+# endif
+# endif
+# if defined(__i386__) || defined(__x86_64__)
+# define GC_CAN_SAVE_CALL_STACKS
+# endif
+#endif
+
+#if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS)
+# define GC_CAN_SAVE_CALL_STACKS
+#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
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) \
# 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) \
/* Finalization. Some of these primitives are grossly unsafe. */
/* The idea is to make them both cheap, and sufficient to build */
-/* a safer layer, closer to PCedar finalization. */
+/* a safer layer, closer to Modula-3, Java, or PCedar finalization. */
/* The interface represents my conclusions from a long discussion */
/* with Alan Demers, Dan Greene, Carl Hauser, Barry Hayes, */
/* Christian Jacobi, and Russ Atkinson. It's not perfect, and */
/* 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
/* 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));
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. Java-like) finalization facility. It is expected */
/* The following routines are primarily intended for use with a */
/* preprocessor which inserts calls to check C pointer arithmetic. */
+/* They indicate failure by invoking the corresponding _print_proc. */
/* Check that p and q point to the same object. */
/* Fail conspicuously if they don't. */
# define GC_PTR_STORE(p, q) *((p) = (q))
#endif
-/* Fynctions called to report pointer checking errors */
+/* Functions called to report pointer checking errors */
GC_API void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR p, GC_PTR q));
GC_API void (*GC_is_valid_displacement_print_proc)
#endif /* THREADS && !SRC_M3 */
-#if defined(GC_WIN32_THREADS) && defined(_WIN32_WCE)
+#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
# include <windows.h>
/*
+ * 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 WINAPI 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.
*/
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
+# ifndef GC_BUILD
+# define WinMain GC_WinMain
+# define CreateThread GC_CreateThread
+# endif
+# endif /* defined(_WIN32_WCE) */
-#endif
+#endif /* defined(GC_WIN32_THREADS) && !cygwin */
-/*
- * If you are planning on putting
- * the collector in a SunOS 5 dynamic library, you need to call GC_INIT()
- * from the statically loaded program section.
- * This circumvents a Solaris 2.X (X<=4) linker bug.
- */
-#if defined(sparc) || defined(__sparc)
+ /*
+ * Fully portable code should call GC_INIT() from the main program
+ * before making any other GC_ calls. On most platforms this is a
+ * no-op and the collector self-initializes. But a number of platforms
+ * make that too hard.
+ */
+#if (defined(sparc) || defined(__sparc)) && defined(sun)
+ /*
+ * If you are planning on putting
+ * the collector in a SunOS 5 dynamic library, you need to call GC_INIT()
+ * from the statically loaded program section.
+ * This circumvents a Solaris 2.X (X<=4) linker bug.
+ */
# define GC_INIT() { extern end, etext; \
GC_noop(&end, &etext); }
#else
-# if (defined(__CYGWIN32__) && defined(GC_USE_DLL)) || defined (_AIX)
+# 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__) || defined(GC_WIN32_THREADS)
+# define GC_INIT() { GC_init(); }
+# else
# define GC_INIT()
-# endif
-#endif
+# endif /* !__MACH && !GC_WIN32_THREADS */
+# endif /* !AIX && !cygwin */
+#endif /* !sparc */
#if !defined(_WIN32_WCE) \
&& ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \