version 1.4, 2001/04/20 07:39:18 |
version 1.7, 2003/06/24 05:11:32 |
Line 202 signed_word * log_size_ptr; |
|
Line 202 signed_word * log_size_ptr; |
|
} |
} |
new_dl = (struct disappearing_link *) |
new_dl = (struct disappearing_link *) |
GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); |
GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); |
if (new_dl != 0) { |
if (0 == new_dl) { |
new_dl -> dl_hidden_obj = HIDE_POINTER(obj); |
# ifdef THREADS |
new_dl -> dl_hidden_link = HIDE_POINTER(link); |
UNLOCK(); |
dl_set_next(new_dl, dl_head[index]); |
ENABLE_SIGNALS(); |
dl_head[index] = new_dl; |
# endif |
GC_dl_entries++; |
new_dl = (struct disappearing_link *) |
} else { |
GC_oom_fn(sizeof(struct disappearing_link)); |
GC_finalization_failures++; |
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 |
# ifdef THREADS |
UNLOCK(); |
UNLOCK(); |
ENABLE_SIGNALS(); |
ENABLE_SIGNALS(); |
Line 245 signed_word * log_size_ptr; |
|
Line 258 signed_word * log_size_ptr; |
|
UNLOCK(); |
UNLOCK(); |
ENABLE_SIGNALS(); |
ENABLE_SIGNALS(); |
# ifdef DBG_HDRS_ALL |
# ifdef DBG_HDRS_ALL |
dl_next(curr_dl) = 0; |
dl_set_next(curr_dl, 0); |
# else |
# else |
GC_free((GC_PTR)curr_dl); |
GC_free((GC_PTR)curr_dl); |
# endif |
# endif |
Line 416 finalization_mark_proc * mp; |
|
Line 429 finalization_mark_proc * mp; |
|
} |
} |
new_fo = (struct finalizable_object *) |
new_fo = (struct finalizable_object *) |
GC_INTERNAL_MALLOC(sizeof(struct finalizable_object),NORMAL); |
GC_INTERNAL_MALLOC(sizeof(struct finalizable_object),NORMAL); |
if (new_fo != 0) { |
if (0 == new_fo) { |
new_fo -> fo_hidden_base = (word)HIDE_POINTER(base); |
# ifdef THREADS |
new_fo -> fo_fn = fn; |
UNLOCK(); |
new_fo -> fo_client_data = (ptr_t)cd; |
ENABLE_SIGNALS(); |
new_fo -> fo_object_size = hhdr -> hb_sz; |
# endif |
new_fo -> fo_mark_proc = mp; |
new_fo = (struct finalizable_object *) |
fo_set_next(new_fo, fo_head[index]); |
GC_oom_fn(sizeof(struct finalizable_object)); |
GC_fo_entries++; |
if (0 == new_fo) { |
fo_head[index] = new_fo; |
GC_finalization_failures++; |
} else { |
return; |
GC_finalization_failures++; |
} |
|
/* 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 |
# ifdef THREADS |
UNLOCK(); |
UNLOCK(); |
ENABLE_SIGNALS(); |
ENABLE_SIGNALS(); |
Line 593 void GC_finalize() |
|
Line 619 void GC_finalize() |
|
GC_words_finalized += |
GC_words_finalized += |
ALIGNED_WORDS(curr_fo -> fo_object_size) |
ALIGNED_WORDS(curr_fo -> fo_object_size) |
+ ALIGNED_WORDS(sizeof(struct finalizable_object)); |
+ 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; |
curr_fo = next_fo; |
} else { |
} else { |
prev_fo = curr_fo; |
prev_fo = curr_fo; |
Line 735 int GC_should_invoke_finalizers GC_PROTO((void)) |
|
Line 761 int GC_should_invoke_finalizers GC_PROTO((void)) |
|
/* Should be called without allocation lock. */ |
/* Should be called without allocation lock. */ |
int GC_invoke_finalizers() |
int GC_invoke_finalizers() |
{ |
{ |
register struct finalizable_object * curr_fo; |
struct finalizable_object * curr_fo; |
register int count = 0; |
int count = 0; |
|
word mem_freed_before; |
DCL_LOCK_STATE; |
DCL_LOCK_STATE; |
|
|
while (GC_finalize_now != 0) { |
while (GC_finalize_now != 0) { |
Line 744 int GC_invoke_finalizers() |
|
Line 771 int GC_invoke_finalizers() |
|
DISABLE_SIGNALS(); |
DISABLE_SIGNALS(); |
LOCK(); |
LOCK(); |
# endif |
# endif |
|
if (count == 0) { |
|
mem_freed_before = GC_mem_freed; |
|
} |
curr_fo = GC_finalize_now; |
curr_fo = GC_finalize_now; |
# ifdef THREADS |
# ifdef THREADS |
if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo); |
if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo); |
Line 765 int GC_invoke_finalizers() |
|
Line 795 int GC_invoke_finalizers() |
|
GC_free((GC_PTR)curr_fo); |
GC_free((GC_PTR)curr_fo); |
# endif |
# endif |
} |
} |
|
if (count != 0 && mem_freed_before != GC_mem_freed) { |
|
LOCK(); |
|
GC_finalizer_mem_freed += (GC_mem_freed - mem_freed_before); |
|
UNLOCK(); |
|
} |
return count; |
return count; |
} |
} |
|
|
Line 777 void GC_notify_or_invoke_finalizers GC_PROTO((void)) |
|
Line 812 void GC_notify_or_invoke_finalizers GC_PROTO((void)) |
|
if (GC_finalize_now == 0) return; |
if (GC_finalize_now == 0) return; |
if (!GC_finalize_on_demand) { |
if (!GC_finalize_on_demand) { |
(void) GC_invoke_finalizers(); |
(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; |
return; |
} |
} |
if (GC_finalizer_notifier != (void (*) GC_PROTO((void)))0 |
if (GC_finalizer_notifier != (void (*) GC_PROTO((void)))0 |
Line 814 void GC_notify_or_invoke_finalizers GC_PROTO((void)) |
|
Line 851 void GC_notify_or_invoke_finalizers GC_PROTO((void)) |
|
# endif |
# endif |
return(result); |
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 */ |