summaryrefslogtreecommitdiff
path: root/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'alloc.c')
-rw-r--r--alloc.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/alloc.c b/alloc.c
index 7786b13..d0e461b 100644
--- a/alloc.c
+++ b/alloc.c
@@ -78,7 +78,7 @@ char * GC_copyright[] =
{"Copyright 1988,1989 Hans-J. Boehm and Alan J. Demers ",
"Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. ",
"Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. ",
-"Copyright (c) 1999-2000 by Hewlett-Packard Company. All rights reserved. ",
+"Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved. ",
"THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY",
" EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.",
"See source code for details." };
@@ -97,13 +97,17 @@ word GC_free_space_divisor = 3;
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;
+
CLOCK_TYPE GC_start_time; /* Time at which we stopped world. */
/* used only in GC_timeout_stop_func. */
int GC_n_attempts = 0; /* Number of attempts at finishing */
- /* collection within TIME_LIMIT */
+ /* collection within GC_time_limit. */
#if defined(SMALL_CONFIG) || defined(NO_CLOCK)
# define GC_timeout_stop_func GC_never_stop_func
@@ -117,7 +121,7 @@ int GC_n_attempts = 0; /* Number of attempts at finishing */
if ((count++ & 3) != 0) return(0);
GET_TIME(current_time);
time_diff = MS_TIME_DIFF(current_time,GC_start_time);
- if (time_diff >= TIME_LIMIT) {
+ if (time_diff >= GC_time_limit) {
# ifdef CONDPRINT
if (GC_print_stats) {
GC_printf0("Abandoning stopped marking after ");
@@ -154,7 +158,7 @@ static word min_words_allocd()
+ (GC_large_free_bytes >> 2)
/* use a bit more of large empty heap */
+ total_root_size);
- if (GC_incremental) {
+ if (TRUE_INCREMENTAL) {
return scan_size / (2 * GC_free_space_divisor);
} else {
return scan_size / GC_free_space_divisor;
@@ -275,9 +279,10 @@ void GC_maybe_gc()
/* If we run out of time, this turns into */
/* incremental marking. */
# ifndef NO_CLOCK
- GET_TIME(GC_start_time);
+ if (GC_time_limit != GC_TIME_UNLIMITED) { GET_TIME(GC_start_time); }
# endif
- if (GC_stopped_mark(GC_timeout_stop_func)) {
+ if (GC_stopped_mark(GC_time_limit == GC_TIME_UNLIMITED?
+ GC_never_stop_func : GC_timeout_stop_func)) {
# ifdef SAVE_CALL_CHAIN
GC_save_callers(GC_last_stack);
# endif
@@ -389,7 +394,8 @@ int n;
# ifdef PARALLEL_MARK
GC_wait_for_reclaim();
# endif
- if (GC_n_attempts < MAX_PRIOR_ATTEMPTS) {
+ if (GC_n_attempts < MAX_PRIOR_ATTEMPTS
+ && GC_time_limit != GC_TIME_UNLIMITED) {
GET_TIME(GC_start_time);
if (!GC_stopped_mark(GC_timeout_stop_func)) {
GC_n_attempts++;
@@ -434,7 +440,7 @@ GC_stop_func stop_func;
{
register int i;
int dummy;
-# ifdef PRINTTIMES
+# if defined(PRINTTIMES) || defined(CONDPRINT)
CLOCK_TYPE start_time, current_time;
# endif
@@ -442,6 +448,9 @@ GC_stop_func stop_func;
# ifdef PRINTTIMES
GET_TIME(start_time);
# endif
+# if defined(CONDPRINT) && !defined(PRINTTIMES)
+ if (GC_print_stats) GET_TIME(start_time);
+# endif
# ifdef CONDPRINT
if (GC_print_stats) {
GC_printf1("--> Marking for collection %lu ",
@@ -451,6 +460,11 @@ GC_stop_func stop_func;
(unsigned long) WORDS_TO_BYTES(GC_words_wasted));
}
# endif
+# ifdef MAKE_BACK_GRAPH
+ if (GC_print_back_height) {
+ GC_build_back_graph();
+ }
+# endif
/* Mark from all roots. */
/* Minimize junk left in my registers and on the stack */
@@ -504,6 +518,14 @@ GC_stop_func stop_func;
GET_TIME(current_time);
GC_printf1("World-stopped marking took %lu msecs\n",
MS_TIME_DIFF(current_time,start_time));
+# else
+# ifdef CONDPRINT
+ if (GC_print_stats) {
+ GET_TIME(current_time);
+ GC_printf1("World-stopped marking took %lu msecs\n",
+ MS_TIME_DIFF(current_time,start_time));
+ }
+# endif
# endif
START_WORLD();
return(TRUE);
@@ -610,6 +632,17 @@ void GC_finish_collection()
GET_TIME(finalize_time);
# endif
+ if (GC_print_back_height) {
+# ifdef MAKE_BACK_GRAPH
+ GC_traverse_back_graph();
+# else
+# ifndef SMALL_CONFIG
+ GC_err_printf0("Back height not available: "
+ "Rebuild collector with -DMAKE_BACK_GRAPH\n");
+# endif
+# endif
+ }
+
/* Clear free list mark bits, in case they got accidentally marked */
/* (or GC_find_leak is set and they were intentionally marked). */
/* Also subtract memory remaining from GC_mem_found count. */
@@ -965,25 +998,32 @@ ptr_t GC_allocobj(sz, kind)
word sz;
int kind;
{
- register ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);
+ ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);
+ GC_bool tried_minor = FALSE;
if (sz == 0) return(0);
while (*flh == 0) {
ENTER_GC();
/* Do our share of marking work */
- if(GC_incremental && !GC_dont_gc) GC_collect_a_little_inner(1);
+ if(TRUE_INCREMENTAL && !GC_dont_gc) GC_collect_a_little_inner(1);
/* Sweep blocks for objects of this size */
- GC_continue_reclaim(sz, kind);
+ GC_continue_reclaim(sz, kind);
EXIT_GC();
if (*flh == 0) {
GC_new_hblk(sz, kind);
}
if (*flh == 0) {
ENTER_GC();
- if (!GC_collect_or_expand((word)1,FALSE)) {
+ if (GC_incremental && GC_time_limit == GC_TIME_UNLIMITED
+ && ! tried_minor ) {
+ GC_collect_a_little_inner(1);
+ tried_minor = TRUE;
+ } else {
+ if (!GC_collect_or_expand((word)1,FALSE)) {
EXIT_GC();
return(0);
+ }
}
EXIT_GC();
}