+2008-08-26 Hans Boehm <Hans.Boehm@hp.com> (with help from Marco Maggi)
+ * configure.ac: Check for gc-debug earlier; replace remaining
+ full-debug tests.
+ * configure: Regenerate.
+ * include/gc.h, ptr_chck.c (GC_pre_incr, GC_post_incr):
+ Use signed offset type. Use ptr_t internally.
+ * doc/gcinterface.html: Update LOCAL_MALLOC description.
+ * doc/README.autoconf, doc/leak.html, doc/README.DGUX386:
+ Fix full-debug reference.
+ * include/gc.h: Rewrite GC_..._INCR and friends.
+ * tests/test.c: Minimally test GC_..._INCR and friends.
+
2008-08-21 Hans Boehm <Hans.Boehm@hp.com>
* mark.c: (GC_push_next_marked, GC_push_next_marked_dirty,
GC_push_next_marked_uncollectable): Never invoke GC_push_marked
#! /bin/sh
-# From configure.ac Revision: 1.38 .
+# From configure.ac Revision: 1.39 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for gc 7.2alpha1.
#
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--disable-gcj-support Disable support for gcj.
+ --enable-gc-debug include full support for pointer backtracing etc.
--disable-java-finalization
Disable support for java finalization.
--disable-atomic-uncollectible
--enable-redirect-malloc
Redirect malloc and friends to GC routines
--enable-large-config Optimize for large (> 100 MB) heap or root set
- --enable-gc-debug include full support for pointer backtracing etc.
--enable-gc-assertions collector-internal assertion checking
--enable-munmap=N return page to the os if empty for N collections
#
# Check for AViiON Machines running DGUX
+# FIXME: Should this be moved down to below the gc-debug processing?
#
ac_is_dgux=no
if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then
## :GOTCHA: we do not check anything but sys/dg_sys_info.h
if test $ac_is_dgux = yes; then
- if test "$enable_full_debug" = "yes"; then
+ if test "$enable_gc_debug" = "yes"; then
CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
else
fi
-# Check whether --enable-java-finalization was given.
-if test "${enable_java_finalization+set}" = set; then
- enableval=$enable_java_finalization;
-fi
-
-if test x"$enable_java_finalization" != xno; then
- cat >>confdefs.h <<\_ACEOF
-#define JAVA_FINALIZATION 1
-_ACEOF
-
-fi
-
-# Check whether --enable-atomic-uncollectable was given.
-if test "${enable_atomic_uncollectable+set}" = set; then
- enableval=$enable_atomic_uncollectable;
-fi
-
-if test x"$enable_atomic_uncollectible" != x"no"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define ATOMIC_UNCOLLECTABLE 1
-_ACEOF
-
-fi
-
-# Check whether --enable-redirect-malloc was given.
-if test "${enable_redirect_malloc+set}" = set; then
- enableval=$enable_redirect_malloc;
-fi
-
-
-if test "${enable_redirect_malloc}" = yes; then
- if test "${enable_full_debug}" = yes; then
- cat >>confdefs.h <<\_ACEOF
-#define REDIRECT_MALLOC GC_debug_malloc_replacement
-_ACEOF
-
- cat >>confdefs.h <<\_ACEOF
-#define REDIRECT_REALLOC GC_debug_realloc_replacement
-_ACEOF
-
- cat >>confdefs.h <<\_ACEOF
-#define REDIRECT_FREE GC_debug_free
-_ACEOF
-
- else
- cat >>confdefs.h <<\_ACEOF
-#define REDIRECT_MALLOC GC_malloc
-_ACEOF
-
- fi
- cat >>confdefs.h <<\_ACEOF
-#define GC_USE_DLOPEN_WRAP 1
-_ACEOF
-
-fi
-
-# Check whether --enable-large-config was given.
-if test "${enable_large_config+set}" = set; then
- enableval=$enable_large_config;
-fi
-
-
-if test "${enable_large_config}" = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define LARGE_CONFIG 1
-_ACEOF
-
-fi
-
-if test -n "${with_cross_host}"; then
- cat >>confdefs.h <<\_ACEOF
-#define NO_CLOCK 1
-_ACEOF
-
- cat >>confdefs.h <<\_ACEOF
-#define SMALL_CONFIG 1
-_ACEOF
-
- cat >>confdefs.h <<\_ACEOF
-#define NO_DEBUGGING 1
-_ACEOF
-
-fi
-
-
UNWINDLIBS=
# Check whether --enable-gc-debug was given.
fi
+# Check whether --enable-java-finalization was given.
+if test "${enable_java_finalization+set}" = set; then
+ enableval=$enable_java_finalization;
+fi
+
+if test x"$enable_java_finalization" != xno; then
+ cat >>confdefs.h <<\_ACEOF
+#define JAVA_FINALIZATION 1
+_ACEOF
+
+fi
+
+# Check whether --enable-atomic-uncollectable was given.
+if test "${enable_atomic_uncollectable+set}" = set; then
+ enableval=$enable_atomic_uncollectable;
+fi
+
+if test x"$enable_atomic_uncollectible" != x"no"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ATOMIC_UNCOLLECTABLE 1
+_ACEOF
+
+fi
+
+# Check whether --enable-redirect-malloc was given.
+if test "${enable_redirect_malloc+set}" = set; then
+ enableval=$enable_redirect_malloc;
+fi
+
+
+if test "${enable_redirect_malloc}" = yes; then
+ if test "${enable_gc_debug}" = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define REDIRECT_MALLOC GC_debug_malloc_replacement
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define REDIRECT_REALLOC GC_debug_realloc_replacement
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define REDIRECT_FREE GC_debug_free
+_ACEOF
+
+ else
+ cat >>confdefs.h <<\_ACEOF
+#define REDIRECT_MALLOC GC_malloc
+_ACEOF
+
+ fi
+ cat >>confdefs.h <<\_ACEOF
+#define GC_USE_DLOPEN_WRAP 1
+_ACEOF
+
+fi
+
+# Check whether --enable-large-config was given.
+if test "${enable_large_config+set}" = set; then
+ enableval=$enable_large_config;
+fi
+
+
+if test "${enable_large_config}" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define LARGE_CONFIG 1
+_ACEOF
+
+fi
+
+if test -n "${with_cross_host}"; then
+ cat >>confdefs.h <<\_ACEOF
+#define NO_CLOCK 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define SMALL_CONFIG 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define NO_DEBUGGING 1
+_ACEOF
+
+fi
+
+
# Check whether --enable-gc-assertions was given.
AC_CONFIG_SRCDIR(gcj_mlc.c)
AC_CANONICAL_TARGET
AC_PREREQ(2.53)
-AC_REVISION($Revision: 1.39 $)
+AC_REVISION($Revision: 1.40 $)
GC_SET_VERSION
AM_INIT_AUTOMAKE([foreign dist-bzip2 subdir-objects nostdinc])
AM_MAINTAINER_MODE
#
# Check for AViiON Machines running DGUX
+# FIXME: Should this be moved down to below the gc-debug processing?
#
ac_is_dgux=no
AC_CHECK_HEADER(sys/dg_sys_info.h,
## :GOTCHA: we do not check anything but sys/dg_sys_info.h
if test $ac_is_dgux = yes; then
- if test "$enable_full_debug" = "yes"; then
+ if test "$enable_gc_debug" = "yes"; then
CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
else
AC_DEFINE(GC_GCJ_SUPPORT, 1, [Define to include support for gcj])
fi
+dnl Debugging
+dnl ---------
+
+UNWINDLIBS=
+AC_ARG_ENABLE(gc-debug,
+[AC_HELP_STRING([--enable-gc-debug],
+ [include full support for pointer backtracing etc.])],
+[ if test "$enable_gc_debug" = "yes"; then
+ AC_MSG_WARN("Should define GC_DEBUG and use debug alloc. in clients.")
+ AC_DEFINE(KEEP_BACK_PTRS)
+ AC_DEFINE(DBG_HDRS_ALL)
+ case $host in
+ ia64-*-linux* )
+ AC_DEFINE(MAKE_BACK_GRAPH)
+ AC_DEFINE(SAVE_CALL_COUNT, 8)
+ AC_CHECK_LIB(unwind, backtrace, [
+ AC_DEFINE(GC_HAVE_BUILTIN_BACKTRACE)
+ UNWINDLIBS=-lunwind
+ AC_MSG_WARN("Client code may need to link against libunwind.")
+ ])
+ ;;
+ x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
+ AC_DEFINE(MAKE_BACK_GRAPH)
+ AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
+ AC_DEFINE(SAVE_CALL_COUNT, 8)
+ ;;
+ i[3456]86-*-dgux*)
+ AC_DEFINE(MAKE_BACK_GRAPH)
+ ;;
+ esac ]
+ fi)
+
AC_ARG_ENABLE(java-finalization,
[AC_HELP_STRING([--disable-java-finalization],
[Disable support for java finalization.])])
[Redirect malloc and friends to GC routines])])
if test "${enable_redirect_malloc}" = yes; then
- if test "${enable_full_debug}" = yes; then
+ if test "${enable_gc_debug}" = yes; then
AC_DEFINE(REDIRECT_MALLOC, GC_debug_malloc_replacement)
AC_DEFINE(REDIRECT_REALLOC, GC_debug_realloc_replacement)
AC_DEFINE(REDIRECT_FREE, GC_debug_free)
fi
-dnl Debugging
-dnl ---------
-
-UNWINDLIBS=
-AC_ARG_ENABLE(gc-debug,
-[AC_HELP_STRING([--enable-gc-debug],
- [include full support for pointer backtracing etc.])],
-[ if test "$enable_gc_debug" = "yes"; then
- AC_MSG_WARN("Should define GC_DEBUG and use debug alloc. in clients.")
- AC_DEFINE(KEEP_BACK_PTRS)
- AC_DEFINE(DBG_HDRS_ALL)
- case $host in
- ia64-*-linux* )
- AC_DEFINE(MAKE_BACK_GRAPH)
- AC_DEFINE(SAVE_CALL_COUNT, 8)
- AC_CHECK_LIB(unwind, backtrace, [
- AC_DEFINE(GC_HAVE_BUILTIN_BACKTRACE)
- UNWINDLIBS=-lunwind
- AC_MSG_WARN("Client code may need to link against libunwind.")
- ])
- ;;
- x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
- AC_DEFINE(MAKE_BACK_GRAPH)
- AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
- AC_DEFINE(SAVE_CALL_COUNT, 8)
- ;;
- i[3456]86-*-dgux*)
- AC_DEFINE(MAKE_BACK_GRAPH)
- ;;
- esac ]
- fi)
-
AC_SUBST(UNWINDLIBS)
AC_ARG_ENABLE(gc-assertions,
to build only the static version of libgc.
To enable debugging messages please do:
- 1) Add the "--enable-full-debug" flag during configuration.
+ 1) Add the "--enable-gc-debug" flag during configuration.
2) Edit the file linux-threads.c and uncommnect the line:
/* #define DEBUG_THREADS 1 */ to --->
[same as prefix]
--enable-threads=TYPE choose threading package
--enable-parallel-mark parallelize marking and free list construction
- --enable-full-debug include full support for pointer backtracing etc.
+ --enable-gc-debug (--enable-full-debug before about 7.0)
+ include full support for pointer backtracing etc.
+
Unless --prefix is set (or --exec-prefix or one of the more obscure options),
make install will install libgc.a and libgc.so in /usr/local/bin, which
</dl>
<P>
If you are concerned with multiprocessor performance and scalability,
-you should consider enabling and using thread local allocation (<I>e.g.</i>
-<TT>GC_LOCAL_MALLOC</tt>, see <TT>gc_local_alloc.h</tt>. If your platform
+you should consider enabling and using thread local allocation.
+For GC versions before 7.0, use <I>e.g.</i>
+<TT>GC_LOCAL_MALLOC</tt> and see <TT>gc_local_alloc.h</tt>;
+for later versions enabling thread-local allocations when the collector
+library is built changes the
+implementation of <TT>GC_MALLOC</tt>, so the client doesn't need to
+change.
+<P>
+If your platform
supports it, you should build the collector with parallel marking support
(<TT>-DPARALLEL_MARK</tt>, or <TT>--enable-parallel-mark</tt>).
<P>
improve the quality of the leak reports.
<LI> Build the collector and install it in directory <I>foo</i> as follows:
<UL>
-<LI> <TT>configure --prefix=<I>foo</i> --enable-full-debug --enable-redirect-malloc
+<LI> <TT>configure --prefix=<I>foo</i> --enable-gc-debug --enable-redirect-malloc
--disable-threads</tt>
<LI> <TT>make</tt>
<LI> <TT>make install</tt>
/* the second argument is in units of bytes, not multiples of the */
/* object size. This should either be invoked from a macro, or the */
/* call should be automatically generated. */
-GC_API void * GC_pre_incr (void * *p, size_t how_much);
-GC_API void * GC_post_incr (void * *p, size_t how_much);
+GC_API void * GC_pre_incr (void * *p, ptrdiff_t how_much);
+GC_API void * GC_post_incr (void * *p, ptrdiff_t how_much);
/* Check that p is visible */
/* to the collector as a possibly pointer containing location. */
/* Safer, but slow, pointer addition. Probably useful mainly with */
/* a preprocessor. Useful only for heap pointers. */
-#ifdef GC_DEBUG
+/* Only the macros without trailing digits are meant to be used */
+/* by clients. These are designed to model the available C pointer */
+/* arithmetic expressions. */
+/* Even then, these are probably more useful as */
+/* documentation than as part of the API. */
+/* Note that GC_PTR_ADD evaluates the first argument more than once. */
+#if defined(GC_DEBUG) && defined(__GNUC__)
# define GC_PTR_ADD3(x, n, type_of_result) \
((type_of_result)GC_same_obj((x)+(n), (x)))
# define GC_PRE_INCR3(x, n, type_of_result) \
- ((type_of_result)GC_pre_incr(&(x), (n)*sizeof(*x))
-# define GC_POST_INCR2(x, type_of_result) \
- ((type_of_result)GC_post_incr(&(x), sizeof(*x))
-# ifdef __GNUC__
-# define GC_PTR_ADD(x, n) \
+ ((type_of_result)GC_pre_incr(&(x), (n)*sizeof(*x)))
+# define GC_POST_INCR3(x, n, type_of_result) \
+ ((type_of_result)GC_post_incr(&(x), (n)*sizeof(*x)))
+# define GC_PTR_ADD(x, n) \
GC_PTR_ADD3(x, n, typeof(x))
-# define GC_PRE_INCR(x, n) \
+# define GC_PRE_INCR(x, n) \
GC_PRE_INCR3(x, n, typeof(x))
-# define GC_POST_INCR(x, n) \
- GC_POST_INCR3(x, typeof(x))
-# else
+# define GC_POST_INCR(x) \
+ GC_POST_INCR3(x, 1, typeof(x))
+# define GC_POST_DECR(x) \
+ GC_POST_INCR3(x, -1, typeof(x))
+#else /* !GC_DEBUG || !__GNUC__ */
/* We can't do this right without typeof, which ANSI */
- /* decided was not sufficiently useful. Repeatedly */
- /* mentioning the arguments seems too dangerous to be */
- /* useful. So does not casting the result. */
-# define GC_PTR_ADD(x, n) ((x)+(n))
-# endif
-#else /* !GC_DEBUG */
-# define GC_PTR_ADD3(x, n, type_of_result) ((x)+(n))
+ /* decided was not sufficiently useful. Without it */
+ /* we resort to the non-debug version. */
+ /* FIXME: This should eventially support C++0x decltype */
# define GC_PTR_ADD(x, n) ((x)+(n))
-# define GC_PRE_INCR3(x, n, type_of_result) ((x) += (n))
# define GC_PRE_INCR(x, n) ((x) += (n))
-# define GC_POST_INCR2(x, n, type_of_result) ((x)++)
-# define GC_POST_INCR(x, n) ((x)++)
+# define GC_POST_INCR(x) ((x)++)
+# define GC_POST_DECR(x) ((x)--)
#endif
/* Safer assignment of a pointer to a nonstack location. */
}
-GC_API void * GC_pre_incr (void **p, size_t how_much)
+GC_API void * GC_pre_incr (void **p, ptrdiff_t how_much)
{
void * initial = *p;
- void * result = GC_same_obj((void *)((word)initial + how_much), initial);
+ void * result = GC_same_obj((void *)((ptr_t)initial + how_much), initial);
if (!GC_all_interior_pointers) {
(void) GC_is_valid_displacement(result);
return (*p = result);
}
-GC_API void * GC_post_incr (void **p, size_t how_much)
+GC_API void * GC_post_incr (void **p, ptrdiff_t how_much)
{
void * initial = *p;
- void * result = GC_same_obj((void *)((word)initial + how_much), initial);
+ void * result = GC_same_obj((void *)((ptr_t)initial + how_much), initial);
if (!GC_all_interior_pointers) {
(void) GC_is_valid_displacement(result);
GC_is_visible_print_proc = fail_proc1;
collectable_count += 1;
x = GC_malloc(16);
- if (GC_base(x + 13) != x) {
+ if (GC_base(GC_PTR_ADD(x, 13)) != x) {
GC_printf("GC_base(heap ptr) produced incorrect result\n");
FAIL;
}
+ GC_PRE_INCR(x, 0);
+ GC_POST_INCR(x);
+ GC_POST_DECR(x);
+ if (GC_base(x) != x) {
+ GC_printf("Bad INCR/DECR result\n");
+ FAIL;
+ }
# ifndef PCR
if (GC_base(y) != 0) {
GC_printf("GC_base(fn_ptr) produced incorrect result\n");