version 1.1.1.1, 1999/12/03 07:39:09 |
version 1.3, 2000/12/01 09:26:10 |
|
|
/* |
/* |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. |
* 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 |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
|
|
# include "gc_priv.h" |
# include "gc_priv.h" |
# include "gc_mark.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. */ |
/* Type of mark procedure used for marking from finalizable object. */ |
/* This procedure normally does not mark the object, only its */ |
/* This procedure normally does not mark the object, only its */ |
/* descendents. */ |
/* descendents. */ |
|
|
|
|
/* Possible finalization_marker procedures. Note that mark stack */ |
/* Possible finalization_marker procedures. Note that mark stack */ |
/* overflow is handled by the caller, and is not a disaster. */ |
/* 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; |
ptr_t p; |
{ |
{ |
hdr * hhdr = HDR(p); |
hdr * hhdr = HDR(p); |
|
|
/* This only pays very partial attention to the mark descriptor. */ |
/* This only pays very partial attention to the mark descriptor. */ |
/* It does the right thing for normal and atomic objects, and treats */ |
/* It does the right thing for normal and atomic objects, and treats */ |
/* most others as normal. */ |
/* 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; |
ptr_t p; |
{ |
{ |
hdr * hhdr = HDR(p); |
hdr * hhdr = HDR(p); |
|
|
} |
} |
|
|
/*ARGSUSED*/ |
/*ARGSUSED*/ |
void GC_null_finalize_mark_proc(p) |
GC_API void GC_null_finalize_mark_proc(p) |
ptr_t p; |
ptr_t p; |
{ |
{ |
} |
} |
|
|
/* in the nonthreads case, we try to avoid disabling signals, */ |
/* in the nonthreads case, we try to avoid disabling signals, */ |
/* since it can be expensive. Threads packages typically */ |
/* since it can be expensive. Threads packages typically */ |
/* make it cheaper. */ |
/* 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_PTR obj; |
GC_finalization_proc fn; |
GC_finalization_proc fn; |
GC_PTR cd; |
GC_PTR cd; |
Line 522 void GC_finalize() |
|
Line 539 void GC_finalize() |
|
while (curr_fo != 0) { |
while (curr_fo != 0) { |
real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base); |
real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base); |
if (!GC_is_marked(real_ptr)) { |
if (!GC_is_marked(real_ptr)) { |
# ifndef JAVA_FINALIZATION |
if (!GC_java_finalization) { |
GC_set_mark_bit(real_ptr); |
GC_set_mark_bit(real_ptr); |
# endif |
} |
/* Delete from hash table */ |
/* Delete from hash table */ |
next_fo = fo_next(curr_fo); |
next_fo = fo_next(curr_fo); |
if (prev_fo == 0) { |
if (prev_fo == 0) { |
Line 556 void GC_finalize() |
|
Line 573 void GC_finalize() |
|
} |
} |
} |
} |
|
|
# ifdef JAVA_FINALIZATION |
if (GC_java_finalization) { |
/* make sure we mark everything reachable from objects finalized |
/* make sure we mark everything reachable from objects finalized |
using the no_order mark_proc */ |
using the no_order mark_proc */ |
for (curr_fo = GC_finalize_now; |
for (curr_fo = GC_finalize_now; |
curr_fo != NULL; curr_fo = fo_next(curr_fo)) { |
curr_fo != NULL; curr_fo = fo_next(curr_fo)) { |
real_ptr = (ptr_t)curr_fo -> fo_hidden_base; |
real_ptr = (ptr_t)curr_fo -> fo_hidden_base; |
if (!GC_is_marked(real_ptr)) { |
if (!GC_is_marked(real_ptr)) { |
if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) { |
if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) { |
GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc); |
GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc); |
} |
} |
GC_set_mark_bit(real_ptr); |
GC_set_mark_bit(real_ptr); |
} |
} |
} |
} |
# endif |
} |
|
|
/* Remove dangling disappearing links. */ |
/* Remove dangling disappearing links. */ |
for (i = 0; i < dl_size; i++) { |
for (i = 0; i < dl_size; i++) { |
Line 595 void GC_finalize() |
|
Line 612 void GC_finalize() |
|
} |
} |
} |
} |
|
|
#ifdef JAVA_FINALIZATION |
#ifndef JAVA_FINALIZATION_NOT_NEEDED |
|
|
/* Enqueue all remaining finalizers to be run - Assumes lock is |
/* Enqueue all remaining finalizers to be run - Assumes lock is |
* held, and signals are disabled */ |
* held, and signals are disabled */ |
void GC_enqueue_all_finalizers() |
void GC_enqueue_all_finalizers() |
{ |
{ |
struct finalizable_object * curr_fo, * prev_fo, * next_fo; |
struct finalizable_object * curr_fo, * prev_fo, * next_fo; |
ptr_t real_ptr, real_link; |
ptr_t real_ptr; |
register int i; |
register int i; |
int fo_size; |
int fo_size; |
|
|
Line 650 void GC_enqueue_all_finalizers() |
|
Line 667 void GC_enqueue_all_finalizers() |
|
* Unfortunately, the Java standard implies we have to keep running |
* Unfortunately, the Java standard implies we have to keep running |
* finalizers until there are no more left, a potential infinite loop. |
* finalizers until there are no more left, a potential infinite loop. |
* YUCK. |
* 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 |
* This routine is externally callable, so is called without |
* the allocation lock. |
* the allocation lock. |
*/ |
*/ |
void GC_finalize_all() |
GC_API void GC_finalize_all() |
{ |
{ |
DCL_LOCK_STATE; |
DCL_LOCK_STATE; |
|
|
Line 671 void GC_finalize_all() |
|
Line 693 void GC_finalize_all() |
|
ENABLE_SIGNALS(); |
ENABLE_SIGNALS(); |
} |
} |
#endif |
#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. */ |
/* Invoke finalizers for all objects that are ready to be finalized. */ |
/* Should be called without allocation lock. */ |
/* Should be called without allocation lock. */ |