[Gc] Dependency tracking for configuration macros

Petter Urkedal urkedal at nbi.dk
Sun May 24 00:39:22 PDT 2009


On 2009-05-22, Boehm, Hans wrote:
> - I'm not enthusiastic about the complicated include chain through gc.h.  Could we include private/config.h from only private/gcconfig.h, and then include that, or gc_priv.h, in the places in which gc.h is being newly included, and possibly in any others it might be needed?  That way this stays out of client visible headers, which I think is the right thing?

I found the problems with the latest patch:

  * gc_config_macros.h depends on GC_CAN_SAVE_CALL_STACKS from gc.h, so
    when I included it from gcconfig.h I saw different code being
    generated on debug configurations.

  * I had rebased my changes on a version which didn't work for me.  Cf. 
    my post to the "Dealing with `.data.rel.ro'" thread.

  * A few more #include-adjustments to the tests.

To solve the first issue, I moved the configuration macros from gc.h to
gc_config_macros.h.  Is that okay?  I also moved the ptr_t definition
from gc_priv.h to gcconfig.h, which also reduce the constraints on the
ordering of includes.
 
I've tested it on a series of random configurations on Linux i386 and
x86_64 by comparing dumps of the object file (after stripping).
Inspection of some of the changed dumps seemed to be due to either
arbitrariness from the code generator (i386 only) or line numbers when
debug assertions were enabled.  (The x86_64 tests where done on a
snapshot just before the .data.rel.ro revision.)

BTW, this may be a know issue, but on i386 with
--enable-redirect-malloc I get random cases of

    GC Warning: USE_PROC_FOR_LIBRARIES + GC_LINUX_THREADS performs poorly.
    Completed 6 tests
    Allocated 11991241 collectable objects
    Allocated 1218 uncollectable objects
    Allocated 7500000 atomic objects
    Allocated 137760 stubborn objects
    Finalized 13216/13216 objects - finalization is probably ok
    Total number of bytes allocated is 569580984
    Final heap size is 95588352 bytes
    Unexpected heap growth - collector may be broken
    Test failed
    /bin/sh: line 4: 31748 Aborted                 ${dir}$tst
    FAIL: gctest


-----%<-----
Dependency tracking for configuration macros:

* configure.ac, acinclude.m4: Invoke AC_CONFIG_HEADER.  Added
documentation of configuration macros.
* configure.ac, Makefile.am: Moved include paths to Makefile.am.  Added
include path for build directory.

* include/gc.h: Use include guards for gc_config_macros.h.
* include/private/gcconfig.h: Also include gc_config_macros.h here, and
include config.h if available.
* include/gc_config_macros.h: Define the include guard.
* include/gc.h, include/gc_config_macros.h: Moved some configuration
macros from the former to the latter to allow inclusion of macros
without including gc.h.

* include/private/gc_priv.h, include/private/gcconfig.h: Moved
definition of ptr_t from former to latter to avoid include-ordering
constraints.

* include/private/gc_priv.h, include/private/gc_pmark.h, backgraph.c,
checksums.c, gcj_mlc.c, real_malloc.c, tests/test.c: Minor adjustments
to make sure that the config macros are defined before use.

* configure.ac: Removed the unused macros STACKBASE and
DATASTART_IS_ETEXT.
* misc.c: Removed unused #undef STACKBASE.
-----%<-----
-------------- next part --------------
diff --git a/Makefile.am b/Makefile.am
index 7a20394..90c5845 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,6 +32,11 @@
 # endif
 SUBDIRS =
 
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \
+	      -DGC_HAVE_PRIVATE_CONFIG_H
+# The GC_HAVE_PRIVATE_CONFIG_H is needed because it's unsafe to rely on
+# HAVE_CONFIG_H in the public gc_version.h header.
+
 # Initialize variables so that we can declare files locally.
 EXTRA_DIST = 
 lib_LTLIBRARIES =
diff --git a/acinclude.m4 b/acinclude.m4
index 97255c8..0c18172 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -37,10 +37,13 @@ AC_DEFUN([GC_SET_VERSION], [
     AC_MSG_ERROR([nonconforming PACKAGE_VERSION='$PACKAGE_VERSION'])
   fi
   
-  AC_DEFINE_UNQUOTED(GC_VERSION_MAJOR, $GC_VERSION_MAJOR)
-  AC_DEFINE_UNQUOTED(GC_VERSION_MINOR, $GC_VERSION_MINOR)
+  AC_DEFINE_UNQUOTED([GC_VERSION_MAJOR], $GC_VERSION_MAJOR,
+		     [The major version number of this GC release.])
+  AC_DEFINE_UNQUOTED([GC_VERSION_MINOR], $GC_VERSION_MINOR,
+		     [The minor version number of this GC release.])
   if test :$GC_ALPHA_VERSION: != :: ; then
-    AC_DEFINE_UNQUOTED(GC_ALPHA_VERSION, $GC_ALPHA_VERSION)
+    AC_DEFINE_UNQUOTED([GC_ALPHA_VERSION], $GC_ALPHA_VERSION,
+		       [The alpha version number, if applicable.])
   fi
   AC_MSG_RESULT(major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \
 ${GC_ALPHA_VERSION:+alpha=}$GC_ALPHA_VERSION)
diff --git a/backgraph.c b/backgraph.c
index 0ca0519..ea14e9b 100644
--- a/backgraph.c
+++ b/backgraph.c
@@ -24,6 +24,8 @@
  * a growing space leak.
  */
 
+#include "private/gcconfig.h"
+
 #ifdef MAKE_BACK_GRAPH
 
 #define MAX_IN	10	/* Maximum in-degree we handle directly */
diff --git a/checksums.c b/checksums.c
index 91f3b28..52ce5e6 100644
--- a/checksums.c
+++ b/checksums.c
@@ -11,10 +11,11 @@
  * modified is included with the above copyright notice.
  */
 /* Boehm, March 29, 1995 12:51 pm PST */
-# ifdef CHECKSUMS
 
 # include "private/gc_priv.h"
 
+# ifdef CHECKSUMS
+
 /* This is debugging code intended to verify the results of dirty bit	*/
 /* computations. Works only in a single threaded environment.		*/
 /* We assume that stubborn objects are changed only when they are 	*/
diff --git a/configure.ac b/configure.ac
index c81a29e..f21ecd2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,7 @@ AC_PREREQ(2.53)
 AC_REVISION($Revision: 1.42 $)
 GC_SET_VERSION
 AM_INIT_AUTOMAKE([foreign dist-bzip2 subdir-objects nostdinc])
+AM_CONFIG_HEADER([include/private/config.h])
 AM_MAINTAINER_MODE
 
 AC_SUBST(PACKAGE)
@@ -68,7 +69,31 @@ AC_ARG_ENABLE(parallel-mark,
 AC_ARG_ENABLE(cplusplus,
     [AC_HELP_STRING([--enable-cplusplus], [install C++ support])])
 
-INCLUDES=-I${srcdir}/include
+dnl Features which may be selected in the folliwng thread-detection switch.
+AH_TEMPLATE([PARALLEL_MARK], [Define to enable parallel marking.])
+AH_TEMPLATE([THREAD_LOCAL_ALLOC],
+	    [Define to enable thread-local allocation optimisation.])
+AH_TEMPLATE([USE_COMPILER_TLS],
+	    [Define to use of compiler-support for thread-local variables.])
+
+dnl Thread selection macros.
+AH_TEMPLATE([GC_AIX_THREADS],       [Define to support IBM AIX threads.])
+AH_TEMPLATE([GC_DARWIN_THREADS],    [Define to support Darwin pthreads.])
+AH_TEMPLATE([GC_FREEBSD_THREADS],   [Define to support FreeBSD pthreads.])
+AH_TEMPLATE([GC_GNU_THREADS],       [Define to support GNU pthreads.])
+AH_TEMPLATE([GC_HPUX_THREADS],      [Define to support HP/UX 11 pthreads.])
+AH_TEMPLATE([GC_IRIX_THREADS],      [Define to support Irix pthreads.])
+AH_TEMPLATE([GC_LINUX_THREADS],     [Define to support pthreads on Linux.])
+AH_TEMPLATE([GC_NETBSD_THREADS],    [Define to support NetBSD pthreads.])
+AH_TEMPLATE([GC_OSF1_THREADS],      [Define to support Tru64 pthreads.])
+AH_TEMPLATE([GC_SOLARIS_THREADS],   [Define to support Solaris pthreads.])
+AH_TEMPLATE([GC_WIN32_THREADS],     [Define to support win32 threads.])
+
+dnl System header feature requests.
+AH_TEMPLATE([_POSIX_C_SOURCE], [The POSIX feature macro.])
+AH_TEMPLATE([_PTHREADS], [Indicates the use of pthreads (NetBSD).])
+
+INCLUDES=
 THREADDLLIBS=
 need_atomic_ops_asm=false
 ## Libraries needed to support dynamic loading and/or threads.
@@ -189,7 +214,7 @@ case "$THREADS" in
     AC_DEFINE(GC_WIN32_THREADS)
     win32_threads=true
     dnl Wine getenv may not return NULL for missing entry
-    AC_DEFINE(NO_GETENV)
+    AC_DEFINE([NO_GETENV], 1, [Define to remove calls to getenv.])
     ;;
  dgux386)
     THREADS=dgux386
@@ -201,8 +226,10 @@ case "$THREADS" in
     fi
     AC_DEFINE(THREAD_LOCAL_ALLOC)
     AC_MSG_WARN("Explict GC_INIT() calls may be required.");
-    AC_DEFINE(GC_DGUX386_THREADS)
-    AC_DEFINE(DGUX_THREADS)
+    AC_DEFINE([GC_DGUX386_THREADS], 1,
+	      [Define to enable support for DB/UX threads on i386.])
+    AC_DEFINE([DGUX_THREADS], 1,
+	      [Define to enable support for DB/UX threads.])
     # Enable _POSIX4A_DRAFT10_SOURCE with flag -pthread
     INCLUDES="-pthread $INCLUDES"
     ;;
@@ -289,7 +316,7 @@ AC_MSG_RESULT($compiler_xlc)
 AM_CONDITIONAL(COMPILER_XLC,test $compiler_xlc = yes)
 if test $compiler_xlc = yes -a "$powerpc_darwin" = true; then
   # the darwin stack-frame-walking code is completely broken on xlc
-  AC_DEFINE(DARWIN_DONT_PARSE_STACK)
+  AC_DEFINE([DARWIN_DONT_PARSE_STACK], 1, [See Makefile.direct])
 fi
 
 # We never want libdl on darwin. It is a fake libdl that just ends up making
@@ -340,7 +367,7 @@ case "$TARGET_ECOS" in
    no)
       ;;
    *)
-      AC_DEFINE(ECOS)
+      AC_DEFINE(ECOS, 1, [Define to enable eCos target support.])
       CXXINCLUDES="-I${TARGET_ECOS}/include"
       addobjs="$addobjs ecos.lo"
       ;;
@@ -383,12 +410,10 @@ case "$host" in
     machdep="mach_dep.lo"
     ;;
  i?86-*-solaris2.[[89]] | i?86-*-solaris2.1?)
-    AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED)
+    AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED, 1, [See gcconfig.h])
     ;;
  mipstx39-*-elf*)
     machdep="mach_dep.lo"
-    AC_DEFINE(STACKBASE, __stackbase)
-    AC_DEFINE(DATASTART_IS_ETEXT)
     ;;
  mips-dec-ultrix*)
     machdep="mach-dep.lo"
@@ -414,7 +439,8 @@ case "$host" in
     ;;
  sparc-sun-solaris2.3)
     machdep="mach_dep.lo sparc_mach_dep.lo"
-    AC_DEFINE(SUNOS53_SHARED_LIB)
+    AC_DEFINE(SUNOS53_SHARED_LIB, 1,
+	      [Define to work around a Solaris 5.3 bug (see dyn_load.c).])
     ;;
  sparc*-sun-solaris2*)
     machdep="mach_dep.lo sparc_mach_dep.lo"
@@ -500,8 +526,10 @@ esac
 
 dnl Include defines that have become de facto standard.
 dnl ALL_INTERIOR_POINTERS can be overridden in startup code.
-AC_DEFINE(NO_EXECUTE_PERMISSION)
-AC_DEFINE(ALL_INTERIOR_POINTERS)
+AC_DEFINE([NO_EXECUTE_PERMISSION], [1],
+	  [Define to allow the collector to disable execute permission of heap objects.])
+AC_DEFINE([ALL_INTERIOR_POINTERS], [1],
+	  [Define to recognise all pointers to the interior of objects.])
 
 
 dnl Interface Selection
@@ -521,14 +549,22 @@ fi
 dnl Debugging
 dnl ---------
 
+AH_TEMPLATE([GC_HAVE_BUILTIN_BACKTRACE],
+	    [Define if backtrace information is supported.])
+AH_TEMPLATE([MAKE_BACK_GRAPH], [See Makefile.direct.])
+AH_TEMPLATE([SAVE_CALL_COUNT],
+	    [The number of caller frames saved when allocating with the
+	     debugging API.])
 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)
+    AC_DEFINE([KEEP_BACK_PTRS], 1,
+	      [Define to save back-pointers in debugging headers.])
+    AC_DEFINE([DBG_HDRS_ALL], 1,
+	      [Define to force debug headers on all objects.])
     case $host in
       ia64-*-linux* )
 	AC_DEFINE(MAKE_BACK_GRAPH)
@@ -554,7 +590,7 @@ AC_ARG_ENABLE(java-finalization,
     [AC_HELP_STRING([--disable-java-finalization],
 	[Disable support for java finalization.])])
 if test x"$enable_java_finalization" != xno; then
-    AC_DEFINE(JAVA_FINALIZATION)
+    AC_DEFINE([JAVA_FINALIZATION], 1, [See Makefile.direct.])
 fi
 
 AC_ARG_ENABLE(atomic-uncollectable,
@@ -571,13 +607,16 @@ AC_ARG_ENABLE(redirect-malloc,
 
 if test "${enable_redirect_malloc}" = 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)
+	AC_DEFINE([REDIRECT_MALLOC], GC_debug_malloc_replacement,
+		  [If defined, redirect malloc to this function.])
+	AC_DEFINE([REDIRECT_REALLOC], GC_debug_realloc_replacement,
+		  [If defined, redirect GC_realloc to this function.])
+	AC_DEFINE([REDIRECT_FREE], GC_debug_free,
+		  [If defined, redirect free to this function.])
     else
 	AC_DEFINE(REDIRECT_MALLOC, GC_malloc)
     fi
-    AC_DEFINE(GC_USE_DLOPEN_WRAP)
+    AC_DEFINE([GC_USE_DLOPEN_WRAP], 1, [See Makefile.direct.])
 fi
 
 AC_ARG_ENABLE(large-config,
@@ -592,9 +631,11 @@ dnl This is something of a hack.  When cross-compiling we turn off
 dnl some functionality.  We also enable the "small" configuration.
 dnl These is only correct when targetting an embedded system.  FIXME.
 if test -n "${with_cross_host}"; then
-   AC_DEFINE(NO_CLOCK)
-   AC_DEFINE(SMALL_CONFIG)
-   AC_DEFINE(NO_DEBUGGING)
+   AC_DEFINE([NO_CLOCK], 1, [Define to not use system clock (cross compiling).])
+   AC_DEFINE([SMALL_CONFIG], 1,
+	     [Define to tune the collector for small heap sizes.])
+   AC_DEFINE([NO_DEBUGGING], 1,
+	     [Disable debugging, like GC_dump and its callees.])
 fi
 
 
@@ -604,7 +645,7 @@ AC_ARG_ENABLE(gc-assertions,
     [AC_HELP_STRING([--enable-gc-assertions],
 	[collector-internal assertion checking])])
 if test "${enable_gc_assertions}" = yes; then
-    AC_DEFINE(GC_ASSERTIONS)
+    AC_DEFINE([GC_ASSERTIONS], 1, [Define to enable internal debug assertions.])
 fi
 
 AC_ARG_ENABLE(munmap,
@@ -618,12 +659,16 @@ AC_ARG_ENABLE(munmap,
     esac]
    )
 if test "${enable_munmap}" != ""; then
-    AC_DEFINE(USE_MMAP)
-    AC_DEFINE(USE_MUNMAP)
+    AC_DEFINE([USE_MMAP], 1,
+	      [Define to use mmap instead of sbrk to expand the heap.])
+    AC_DEFINE([USE_MUNMAP], 1,
+	      [Define to return memory to OS with munmap calls.
+	       See Makefile.direct.])
     if test "${MUNMAP_THRESHOLD}" = "yes"; then
       MUNMAP_THRESHOLD=6
     fi
-    AC_DEFINE_UNQUOTED(MUNMAP_THRESHOLD, ${MUNMAP_THRESHOLD})
+    AC_DEFINE_UNQUOTED([MUNMAP_THRESHOLD], [${MUNMAP_THRESHOLD}],
+	[Number of GC cycles to wait before unmapping an unused block.])
 fi
 
 AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
diff --git a/gcj_mlc.c b/gcj_mlc.c
index 9035f21..41fe9ff 100644
--- a/gcj_mlc.c
+++ b/gcj_mlc.c
@@ -14,6 +14,8 @@
  */
 /* Boehm, July 31, 1995 5:02 pm PDT */
 
+#include "private/gcconfig.h"
+
 #ifdef GC_GCJ_SUPPORT
 
 /*
diff --git a/include/gc.h b/include/gc.h
index 0c232dd..6c03064 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -38,7 +38,9 @@
 	/* dynamic library.  The GC_version variable can be used	*/
 	/* to obtain the latter.					*/
 
-# include "gc_config_macros.h"
+# ifndef GC_CONFIG_MACROS_H
+#   include "gc_config_macros.h"
+# endif
 
 # ifdef __cplusplus
     extern "C" {
@@ -476,59 +478,6 @@ GC_API int GC_CALL GC_collect_a_little(void);
 GC_API void * GC_CALL GC_malloc_ignore_off_page(size_t lb);
 GC_API void * GC_CALL GC_malloc_atomic_ignore_off_page(size_t lb);
 
-#if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
-#   define GC_ADD_CALLER
-#   define GC_RETURN_ADDR (GC_word)__return_address
-#endif
-
-#if defined(__linux__) || defined(__GLIBC__)
-# include <features.h>
-# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-     && !defined(__ia64__) && !defined(__UCLIBC__)
-#   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(_MSC_VER) && _MSC_VER >= 1200 /* version 12.0+ (MSVC 6.0+)  */ \
-    && !defined(_AMD64_)
-# ifndef GC_HAVE_NO_BUILTIN_BACKTRACE
-#   define GC_HAVE_BUILTIN_BACKTRACE
-# 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(__DragonFly__)) & !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, const char * s, int i
diff --git a/include/gc_config_macros.h b/include/gc_config_macros.h
index ac56b71..7b63d09 100644
--- a/include/gc_config_macros.h
+++ b/include/gc_config_macros.h
@@ -5,6 +5,7 @@
  * Some tests for old macros.  These violate our namespace rules and will
  * disappear shortly.  Use the GC_ names.
  */
+#define GC_CONFIG_MACROS_H 1
 #if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) \
     || defined(_SOLARIS_PTHREADS) || defined(GC_SOLARIS_PTHREADS)
   /* We no longer support old style Solaris threads.		*/
@@ -186,3 +187,57 @@
 #ifndef GC_CALLBACK
 # define GC_CALLBACK GC_CALL
 #endif
+
+
+#if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
+#   define GC_ADD_CALLER
+#   define GC_RETURN_ADDR (GC_word)__return_address
+#endif
+
+#if defined(__linux__) || defined(__GLIBC__)
+# include <features.h>
+# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
+     && !defined(__ia64__) && !defined(__UCLIBC__)
+#   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(_MSC_VER) && _MSC_VER >= 1200 /* version 12.0+ (MSVC 6.0+)  */ \
+    && !defined(_AMD64_)
+# ifndef GC_HAVE_NO_BUILTIN_BACKTRACE
+#   define GC_HAVE_BUILTIN_BACKTRACE
+# 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(__DragonFly__)) & !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
diff --git a/include/private/gc_pmark.h b/include/private/gc_pmark.h
index 45346e2..f4a0247 100644
--- a/include/private/gc_pmark.h
+++ b/include/private/gc_pmark.h
@@ -25,15 +25,15 @@
 #ifndef GC_PMARK_H
 # define GC_PMARK_H
 
+# ifndef GC_PRIVATE_H
+#   include "gc_priv.h"
+# endif
 # if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST)
 #   include "dbg_mlc.h"
 # endif
 # ifndef GC_MARK_H
 #   include "../gc_mark.h"
 # endif
-# ifndef GC_PRIVATE_H
-#   include "gc_priv.h"
-# endif
 
 /* The real declarations of the following is in gc_priv.h, so that	*/
 /* we can avoid scanning the following table.				*/
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 1198532..7631320 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -40,6 +40,10 @@
 #   define AO_REQUIRE_CAS
 #endif
 
+# ifndef GCCONFIG_H
+#   include "gcconfig.h"
+# endif
+
 #ifndef _GC_H
 #   include "../gc.h"
 #endif
@@ -60,14 +64,6 @@ typedef int GC_bool;
 # define TRUE 1
 # define FALSE 0
 
-typedef char * ptr_t;	/* A generic pointer to which we can add	*/
-			/* byte displacements and which can be used	*/
-			/* for address comparisons.			*/
-
-# ifndef GCCONFIG_H
-#   include "gcconfig.h"
-# endif
-
 # ifndef HEADERS_H
 #   include "gc_hdrs.h"
 # endif
diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h
index 2b73935..9772140 100644
--- a/include/private/gcconfig.h
+++ b/include/private/gcconfig.h
@@ -26,13 +26,27 @@
 
 # define GCCONFIG_H
 
-# ifndef GC_PRIVATE_H
-    /* Fake ptr_t declaration, just to avoid compilation errors.	*/
-    /* This avoids many instances if "ifndef GC_PRIVATE_H" below.	*/
-    typedef struct GC_undefined_struct * ptr_t;
-#   include <stddef.h>	/* For size_t etc. */
+# if defined(_GC_H)
+#   error "The version checks will fail unless private/gcconfig.h is included"
+#   error "before public headers."
 # endif
 
+# if defined(GC_HAVE_PRIVATE_CONFIG_H) && !defined(GC_PRIVATE_CONFIG_H)
+#   define GC_PRIVATE_CONFIG_H
+#   include "private/config.h"
+# endif
+
+# ifndef GC_CONFIG_MACROS_H
+#   include "../gc_config_macros.h"
+# endif
+
+# include <stddef.h>	/* For size_t etc. */
+
+typedef char * ptr_t;	/* A generic pointer to which we can add	*/
+			/* byte displacements and which can be used	*/
+			/* for address comparisons.			*/
+
+
 /* Machine dependent parameters.  Some tuning parameters can be found	*/
 /* near the top of gc_private.h.					*/
 
@@ -2217,7 +2231,7 @@
   /* at build time, though we feel free to adjust it slightly.		*/
   /* Define NEED_CALLINFO if we either save the call stack or 		*/
   /* GC_ADD_CALLER is defined.						*/
-  /* GC_CAN_SAVE_CALL_STACKS is set in gc.h.				*/
+  /* GC_CAN_SAVE_CALL_STACKS is set in gc_config_macros.h.		*/
 
 #if defined(SPARC)
 # define CAN_SAVE_CALL_ARGS
@@ -2297,7 +2311,6 @@
 #   error "REDIRECT_MALLOC with THREADS works at most on Linux."
 # endif
 
-#ifdef GC_PRIVATE_H
 	/* This relies on some type definitions from gc_priv.h, from	*/
         /* where it's normally included.				*/
 	/*								*/
@@ -2354,6 +2367,4 @@
 #   define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
 # endif
 
-#endif /* GC_PRIVATE_H */
-
 # endif /* GCCONFIG_H */
diff --git a/misc.c b/misc.c
index 1db1415..3543503 100644
--- a/misc.c
+++ b/misc.c
@@ -54,10 +54,6 @@
 /* For other platforms with threads, the lock and possibly		*/
 /* GC_lock_holder variables are defined in the thread support code.	*/
 
-#if defined(NOSYS) || defined(ECOS)
-#undef STACKBASE
-#endif
-
 /* Dont unnecessarily call GC_register_main_static_data() in case 	*/
 /* dyn_load.c isn't linked in.						*/
 #ifdef DYNAMIC_LOADING
diff --git a/real_malloc.c b/real_malloc.c
index 85befdc..23c3c4d 100644
--- a/real_malloc.c
+++ b/real_malloc.c
@@ -14,6 +14,8 @@
 /* Boehm, May 19, 1994 2:04 pm PDT */
 
 
+# include "private/gcconfig.h"
+
 # ifdef PCR
 /*
  * This definition should go in its own file that includes no other
diff --git a/tests/test.c b/tests/test.c
index 023f737..563e0e9 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -20,6 +20,8 @@
 
 # undef GC_BUILD
 
+# include "private/gc_priv.h"	/* For output, locking, MIN_WORDS, 	*/
+				/* and some statistics, and gcconfig.h.	*/
 #ifndef NTHREADS /* Number of additional threads to fork. */
 #  define NTHREADS 5 /* excludes main thread, which also runs a test. */
 	/* Not respected by PCR test. */
@@ -43,8 +45,6 @@
 # endif
 # include "gc.h"
 # include "gc_typed.h"
-# include "private/gc_priv.h"	/* For output, locking, MIN_WORDS, 	*/
-				/* and some statistics, and gcconfig.h.	*/
 
 # if defined(MSWIN32) || defined(MSWINCE)
 #   include <windows.h>
diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc
index 9bf53de..626e19c 100644
--- a/tests/test_cpp.cc
+++ b/tests/test_cpp.cc
@@ -24,10 +24,17 @@ few minutes to complete.
 
 ***************************************************************************/
 
-#include "gc_cpp.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+extern "C" {
+# include "private/gcconfig.h"
+  GC_API void GC_printf(const char *format, ...);
+  /* Use GC private output to reach the same log file.  */
+  /* Don't include gc_priv.h, since that may include Windows system	*/
+  /* header files that don't take kindly to this context.		*/
+}
+#include "gc_cpp.h"
 #define USE_STD_ALLOCATOR
 #ifdef USE_STD_ALLOCATOR
 #   include "gc_allocator.h"
@@ -36,13 +43,6 @@ few minutes to complete.
 #else
 #   include "gc_alloc.h"
 #endif
-extern "C" {
-# include "private/gcconfig.h"
-  GC_API void GC_printf(const char *format, ...);
-  /* Use GC private output to reach the same log file.  */
-  /* Don't include gc_priv.h, since that may include Windows system	*/
-  /* header files that don't take kindly to this context.		*/
-}
 #ifdef MSWIN32
 #   include <windows.h>
 #endif


More information about the Gc mailing list