=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/gc/finalize.c,v retrieving revision 1.4 retrieving revision 1.7 diff -u -p -r1.4 -r1.7 --- OpenXM_contrib2/asir2000/gc/finalize.c 2001/04/20 07:39:18 1.4 +++ OpenXM_contrib2/asir2000/gc/finalize.c 2003/06/24 05:11:32 1.7 @@ -202,15 +202,28 @@ signed_word * log_size_ptr; } new_dl = (struct disappearing_link *) GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); - if (new_dl != 0) { - new_dl -> dl_hidden_obj = HIDE_POINTER(obj); - new_dl -> dl_hidden_link = HIDE_POINTER(link); - dl_set_next(new_dl, dl_head[index]); - dl_head[index] = new_dl; - GC_dl_entries++; - } else { - GC_finalization_failures++; + if (0 == new_dl) { +# ifdef THREADS + UNLOCK(); + ENABLE_SIGNALS(); +# endif + new_dl = (struct disappearing_link *) + GC_oom_fn(sizeof(struct disappearing_link)); + if (0 == new_dl) { + GC_finalization_failures++; + return(0); + } + /* It's not likely we'll make it here, but ... */ +# ifdef THREADS + DISABLE_SIGNALS(); + LOCK(); +# endif } + new_dl -> dl_hidden_obj = HIDE_POINTER(obj); + new_dl -> dl_hidden_link = HIDE_POINTER(link); + dl_set_next(new_dl, dl_head[index]); + dl_head[index] = new_dl; + GC_dl_entries++; # ifdef THREADS UNLOCK(); ENABLE_SIGNALS(); @@ -245,7 +258,7 @@ signed_word * log_size_ptr; UNLOCK(); ENABLE_SIGNALS(); # ifdef DBG_HDRS_ALL - dl_next(curr_dl) = 0; + dl_set_next(curr_dl, 0); # else GC_free((GC_PTR)curr_dl); # endif @@ -416,18 +429,31 @@ finalization_mark_proc * mp; } new_fo = (struct finalizable_object *) GC_INTERNAL_MALLOC(sizeof(struct finalizable_object),NORMAL); - if (new_fo != 0) { - new_fo -> fo_hidden_base = (word)HIDE_POINTER(base); - new_fo -> fo_fn = fn; - new_fo -> fo_client_data = (ptr_t)cd; - new_fo -> fo_object_size = hhdr -> hb_sz; - new_fo -> fo_mark_proc = mp; - fo_set_next(new_fo, fo_head[index]); - GC_fo_entries++; - fo_head[index] = new_fo; - } else { - GC_finalization_failures++; + if (0 == new_fo) { +# ifdef THREADS + UNLOCK(); + ENABLE_SIGNALS(); +# endif + new_fo = (struct finalizable_object *) + GC_oom_fn(sizeof(struct finalizable_object)); + if (0 == new_fo) { + GC_finalization_failures++; + return; + } + /* It's not likely we'll make it here, but ... */ +# ifdef THREADS + DISABLE_SIGNALS(); + LOCK(); +# endif } + new_fo -> fo_hidden_base = (word)HIDE_POINTER(base); + new_fo -> fo_fn = fn; + new_fo -> fo_client_data = (ptr_t)cd; + new_fo -> fo_object_size = hhdr -> hb_sz; + new_fo -> fo_mark_proc = mp; + fo_set_next(new_fo, fo_head[index]); + GC_fo_entries++; + fo_head[index] = new_fo; # ifdef THREADS UNLOCK(); ENABLE_SIGNALS(); @@ -593,7 +619,7 @@ void GC_finalize() GC_words_finalized += ALIGNED_WORDS(curr_fo -> fo_object_size) + ALIGNED_WORDS(sizeof(struct finalizable_object)); - GC_ASSERT(GC_is_marked((ptr_t)curr_fo)); + GC_ASSERT(GC_is_marked(GC_base((ptr_t)curr_fo))); curr_fo = next_fo; } else { prev_fo = curr_fo; @@ -735,8 +761,9 @@ int GC_should_invoke_finalizers GC_PROTO((void)) /* Should be called without allocation lock. */ int GC_invoke_finalizers() { - register struct finalizable_object * curr_fo; - register int count = 0; + struct finalizable_object * curr_fo; + int count = 0; + word mem_freed_before; DCL_LOCK_STATE; while (GC_finalize_now != 0) { @@ -744,6 +771,9 @@ int GC_invoke_finalizers() DISABLE_SIGNALS(); LOCK(); # endif + if (count == 0) { + mem_freed_before = GC_mem_freed; + } curr_fo = GC_finalize_now; # ifdef THREADS if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo); @@ -765,6 +795,11 @@ int GC_invoke_finalizers() GC_free((GC_PTR)curr_fo); # endif } + if (count != 0 && mem_freed_before != GC_mem_freed) { + LOCK(); + GC_finalizer_mem_freed += (GC_mem_freed - mem_freed_before); + UNLOCK(); + } return count; } @@ -777,7 +812,9 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void)) if (GC_finalize_now == 0) return; if (!GC_finalize_on_demand) { (void) GC_invoke_finalizers(); - GC_ASSERT(GC_finalize_now == 0); +# ifndef THREADS + GC_ASSERT(GC_finalize_now == 0); +# endif /* Otherwise GC can run concurrently and add more */ return; } if (GC_finalizer_notifier != (void (*) GC_PROTO((void)))0 @@ -814,3 +851,18 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void)) # endif return(result); } + +#if !defined(NO_DEBUGGING) + +void GC_print_finalization_stats() +{ + struct finalizable_object *fo = GC_finalize_now; + size_t ready = 0; + + GC_printf2("%lu finalization table entries; %lu disappearing links\n", + GC_fo_entries, GC_dl_entries); + for (; 0 != fo; fo = fo_next(fo)) ++ready; + GC_printf1("%lu objects are eligible for immediate finalization\n", ready); +} + +#endif /* NO_DEBUGGING */