+2004-08-27 Hans Boehm <Hans.Boehm@hp.com>
+
+ * backgraph.c, gc_priv.h (GC_traverse_back_graph,
+ GC_print_back_graph_stats): split GC_traverse_back_graph.
+ * backgraph.c: Dynamically grow in_progress_space.
+ * finalize.c (GC_notify_or_invoke_finalizers): also call
+ GC_print_back_graph_stats.
+ * alloc.c, finalize.c, gc_priv.h (GC_generate_random_backtrace_no_gc,
+ GC_print_back_height): Move delarations to header file.
+ * configure.ac: rename --enable-full-debug to --enable-gc-debug.
+ * configure: Regenerate.
+
2004-08-23 Hans Boehm <Hans.Boehm@hp.com>
* aix_irix_threads.c: Move _THREADS checks after gc_priv.h include.
extern GC_bool GC_collection_in_progress();
/* Collection is in progress, or was abandoned. */
-extern GC_bool GC_print_back_height;
-
int GC_never_stop_func GC_PROTO((void)) { return(0); }
unsigned long GC_time_limit = TIME_LIMIT;
{
if (0 == back_edge_space) {
back_edge_space = (back_edges *)
- sbrk(MAX_BACK_EDGE_STRUCTS*sizeof(back_edges));
+ GET_MEM(MAX_BACK_EDGE_STRUCTS*sizeof(back_edges));
}
if (0 != avail_back_edges) {
back_edges * result = avail_back_edges;
/* Table of objects that are currently on the depth-first search */
/* stack. Only objects with in-degree one are in this table. */
/* Other objects are identified using HEIGHT_IN_PROGRESS. */
-/* This data structure NEEDS IMPROVEMENT. */
-#define MAX_IN_PROGRESS 10000
+/* FIXME: This data structure NEEDS IMPROVEMENT. */
+#define INITIAL_IN_PROGRESS 10000
static ptr_t * in_progress_space = 0;
-static int n_in_progress = 0;
+static size_t in_progress_size = 0;
+static size_t n_in_progress = 0;
static void push_in_progress(ptr_t p)
{
+ if (n_in_progress >= in_progress_size)
+ if (in_progress_size == 0) {
+ in_progress_size = INITIAL_IN_PROGRESS;
+ in_progress_space = (ptr_t *)GET_MEM(in_progress_size * sizeof(ptr_t));
+ } else {
+ ptr_t * new_in_progress_space;
+ in_progress_size *= 2;
+ new_in_progress_space = (ptr_t *)
+ GET_MEM(in_progress_size * sizeof(ptr_t));
+ BCOPY(in_progress_space, new_in_progress_space,
+ n_in_progress * sizeof(ptr_t));
+ in_progress_space = new_in_progress_space;
+ /* FIXME: This just drops the old space. */
+ }
if (in_progress_space == 0)
- in_progress_space = sbrk(MAX_IN_PROGRESS * sizeof(ptr_t));
- if (n_in_progress == MAX_IN_PROGRESS)
- ABORT("Exceeded MAX_IN_PROGRESS");
+ ABORT("MAKE_BACK_GRAPH: Out of in-progress space: "
+ "Huge linear data structure?");
in_progress_space[n_in_progress++] = p;
}
}
}
-/* Rebuild the reprentation of the backward reachability graph. */
-/* Does not examine mark bits. Can be called before GC. */
+/* Rebuild the representation of the backward reachability graph. */
+/* Does not examine mark bits. Can be called before GC. */
void GC_build_back_graph(void)
{
GC_apply_to_each_object(add_back_edges);
}
}
+word GC_max_max_height = 0;
+
void GC_traverse_back_graph(void)
{
- static word max_max_height = 0;
GC_max_height = 0;
GC_apply_to_each_object(update_max_height);
+}
+
+void GC_print_back_graph_stats(void)
+{
GC_printf2("Maximum backwards height of reachable objects at GC %lu is %ld\n",
(unsigned long) GC_gc_no, GC_max_height);
- if (GC_max_height > max_max_height) {
- max_max_height = GC_max_height;
+ if (GC_max_height > GC_max_max_height) {
+ GC_max_max_height = GC_max_height;
GC_printf0("The following unreachable object is last in a longest chain "
"of unreachable objects:\n");
GC_print_heap_obj(GC_deepest_obj);
--enable-fast-install=PKGS optimize for fast installation default=yes
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-parallel-mark parallelize marking and free list construction
- --enable-full-debug include full support for pointer backtracing etc.
+ --enable-gc-debug include full support for pointer backtracing etc.
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
fi
-# Check whether --enable-full-debug or --disable-full-debug was given.
-if test "${enable_full_debug+set}" = set; then
- enableval="$enable_full_debug"
- if test "$enable_full_debug" = "yes"; then
+# Check whether --enable-gc-debug or --disable-gc-debug was given.
+if test "${enable_gc_debug+set}" = set; then
+ enableval="$enable_gc_debug"
+ if test "$enable_gc_debug" = "yes"; then
{ echo "$as_me:$LINENO: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&5
echo "$as_me: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&2;}
cat >>confdefs.h <<\_ACEOF
AC_DEFINE(NO_DEBUGGING)
fi
-AC_ARG_ENABLE(full-debug,
-[ --enable-full-debug include full support for pointer backtracing etc.],
-[ if test "$enable_full_debug" = "yes"; then
+AC_ARG_ENABLE(gc-debug,
+[ --enable-gc-debug include full support for pointer backtracing etc.],
+[ if test "$enable_gc_debug" = "yes"; then
AC_MSG_WARN("Must define GC_DEBUG and use debug alloc. in clients.")
AC_DEFINE(KEEP_BACK_PTRS)
AC_DEFINE(DBG_HDRS_ALL)
i[3456]86-*-dgux*)
AC_DEFINE(MAKE_BACK_GRAPH)
;;
- esac ]
- fi)
+ esac
+ fi])
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
static GC_word last_finalizer_notification = 0;
-#ifdef KEEP_BACK_PTRS
-void GC_generate_random_backtrace_no_gc(void);
-#endif
-
void GC_notify_or_invoke_finalizers GC_PROTO((void))
{
/* This is a convenient place to generate backtraces if appropriate, */
/* since that code is not callable with the allocation lock. */
-# ifdef KEEP_BACK_PTRS
- if (GC_backtraces > 0) {
- static word last_back_trace_gc_no = 3; /* Skip early ones. */
- long i;
+# if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
+ static word last_back_trace_gc_no = 1; /* Skip first one. */
- LOCK();
- if (GC_gc_no > last_back_trace_gc_no) {
+ if (GC_gc_no > last_back_trace_gc_no) {
+ word i;
+
+# ifdef KEEP_BACK_PTRS
+ LOCK();
/* Stops when GC_gc_no wraps; that's OK. */
- last_back_trace_gc_no = (word)(-1); /* disable others. */
- for (i = 0; i < GC_backtraces; ++i) {
+ last_back_trace_gc_no = (word)(-1); /* disable others. */
+ for (i = 0; i < GC_backtraces; ++i) {
/* FIXME: This tolerates concurrent heap mutation, */
/* which may cause occasional mysterious results. */
/* We need to release the GC lock, since GC_print_callers */
UNLOCK();
GC_generate_random_backtrace_no_gc();
LOCK();
- }
- last_back_trace_gc_no = GC_gc_no;
- }
- UNLOCK();
+ }
+ last_back_trace_gc_no = GC_gc_no;
+ UNLOCK();
+# endif
+# ifdef MAKE_BACK_GRAPH
+ if (GC_print_back_height)
+ GC_print_back_graph_stats();
+# endif
}
# endif
if (GC_finalize_now == 0) return;
#ifdef KEEP_BACK_PTRS
extern long GC_backtraces;
+ void GC_generate_random_backtrace_no_gc(void);
+#endif
+
+extern GC_bool GC_print_back_height;
+
+#ifdef MAKE_BACK_GRAPH
+ void GC_print_back_graph_stats(void);
#endif
/* Macros used for collector internal allocation. */