=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/gc/finalize.c,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -p -r1.1.1.1 -r1.3 --- OpenXM_contrib2/asir2000/gc/finalize.c 1999/12/03 07:39:09 1.1.1.1 +++ OpenXM_contrib2/asir2000/gc/finalize.c 2000/12/01 09:26:10 1.3 @@ -1,6 +1,7 @@ /* * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. + * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -16,6 +17,18 @@ # include "gc_priv.h" # include "gc_mark.h" +# ifdef FINALIZE_ON_DEMAND + int GC_finalize_on_demand = 1; +# else + int GC_finalize_on_demand = 0; +# endif + +# ifdef JAVA_FINALIZATION + int GC_java_finalization = 1; +# else + int GC_java_finalization = 0; +# endif + /* Type of mark procedure used for marking from finalizable object. */ /* This procedure normally does not mark the object, only its */ /* descendents. */ @@ -249,7 +262,7 @@ out: /* Possible finalization_marker procedures. Note that mark stack */ /* overflow is handled by the caller, and is not a disaster. */ -void GC_normal_finalize_mark_proc(p) +GC_API void GC_normal_finalize_mark_proc(p) ptr_t p; { hdr * hhdr = HDR(p); @@ -261,7 +274,7 @@ ptr_t p; /* This only pays very partial attention to the mark descriptor. */ /* It does the right thing for normal and atomic objects, and treats */ /* most others as normal. */ -void GC_ignore_self_finalize_mark_proc(p) +GC_API void GC_ignore_self_finalize_mark_proc(p) ptr_t p; { hdr * hhdr = HDR(p); @@ -284,7 +297,7 @@ ptr_t p; } /*ARGSUSED*/ -void GC_null_finalize_mark_proc(p) +GC_API void GC_null_finalize_mark_proc(p) ptr_t p; { } @@ -295,7 +308,11 @@ ptr_t p; /* in the nonthreads case, we try to avoid disabling signals, */ /* since it can be expensive. Threads packages typically */ /* make it cheaper. */ -void GC_register_finalizer_inner(obj, fn, cd, ofn, ocd, mp) +/* The last parameter is a procedure that determines */ +/* marking for finalization ordering. Any objects marked */ +/* by that procedure will be guaranteed to not have been */ +/* finalized when this finalizer is invoked. */ +GC_API void GC_register_finalizer_inner(obj, fn, cd, ofn, ocd, mp) GC_PTR obj; GC_finalization_proc fn; GC_PTR cd; @@ -522,9 +539,9 @@ void GC_finalize() while (curr_fo != 0) { real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base); if (!GC_is_marked(real_ptr)) { -# ifndef JAVA_FINALIZATION - GC_set_mark_bit(real_ptr); -# endif + if (!GC_java_finalization) { + GC_set_mark_bit(real_ptr); + } /* Delete from hash table */ next_fo = fo_next(curr_fo); if (prev_fo == 0) { @@ -556,20 +573,20 @@ void GC_finalize() } } -# ifdef JAVA_FINALIZATION - /* make sure we mark everything reachable from objects finalized - using the no_order mark_proc */ - for (curr_fo = GC_finalize_now; - curr_fo != NULL; curr_fo = fo_next(curr_fo)) { - real_ptr = (ptr_t)curr_fo -> fo_hidden_base; - if (!GC_is_marked(real_ptr)) { - if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) { - GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc); - } - GC_set_mark_bit(real_ptr); - } - } -# endif + if (GC_java_finalization) { + /* make sure we mark everything reachable from objects finalized + using the no_order mark_proc */ + for (curr_fo = GC_finalize_now; + curr_fo != NULL; curr_fo = fo_next(curr_fo)) { + real_ptr = (ptr_t)curr_fo -> fo_hidden_base; + if (!GC_is_marked(real_ptr)) { + if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) { + GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc); + } + GC_set_mark_bit(real_ptr); + } + } + } /* Remove dangling disappearing links. */ for (i = 0; i < dl_size; i++) { @@ -595,14 +612,14 @@ void GC_finalize() } } -#ifdef JAVA_FINALIZATION +#ifndef JAVA_FINALIZATION_NOT_NEEDED /* Enqueue all remaining finalizers to be run - Assumes lock is * held, and signals are disabled */ void GC_enqueue_all_finalizers() { struct finalizable_object * curr_fo, * prev_fo, * next_fo; - ptr_t real_ptr, real_link; + ptr_t real_ptr; register int i; int fo_size; @@ -650,10 +667,15 @@ void GC_enqueue_all_finalizers() * Unfortunately, the Java standard implies we have to keep running * finalizers until there are no more left, a potential infinite loop. * YUCK. + * Note that this is even more dangerous than the usual Java + * finalizers, in that objects reachable from static variables + * may have been finalized when these finalizers are run. + * Finalizers run at this point must be prepared to deal with a + * mostly broken world. * This routine is externally callable, so is called without * the allocation lock. */ -void GC_finalize_all() +GC_API void GC_finalize_all() { DCL_LOCK_STATE; @@ -671,6 +693,14 @@ void GC_finalize_all() ENABLE_SIGNALS(); } #endif + +/* Returns true if it is worth calling GC_invoke_finalizers. (Useful if */ +/* finalizers can only be called from some kind of `safe state' and */ +/* getting into that safe state is expensive.) */ +int GC_should_invoke_finalizers GC_PROTO((void)) +{ + return GC_finalize_now != 0; +} /* Invoke finalizers for all objects that are ready to be finalized. */ /* Should be called without allocation lock. */