version 1.6, 2002/07/24 08:00:06 |
version 1.10, 2009/03/10 16:40:45 |
Line 72 int GC_full_freq = 19; /* Every 20th collection is |
|
Line 72 int GC_full_freq = 19; /* Every 20th collection is |
|
GC_bool GC_need_full_gc = FALSE; |
GC_bool GC_need_full_gc = FALSE; |
/* Need full GC do to heap growth. */ |
/* Need full GC do to heap growth. */ |
|
|
|
#ifdef THREADS |
|
GC_bool GC_world_stopped = FALSE; |
|
# define IF_THREADS(x) x |
|
#else |
|
# define IF_THREADS(x) |
|
#endif |
|
|
word GC_used_heap_size_after_full = 0; |
word GC_used_heap_size_after_full = 0; |
|
|
char * GC_copyright[] = |
char * GC_copyright[] = |
Line 93 extern signed_word GC_mem_found; /* Number of reclaim |
|
Line 100 extern signed_word GC_mem_found; /* Number of reclaim |
|
GC_bool GC_dont_expand = 0; |
GC_bool GC_dont_expand = 0; |
|
|
word GC_free_space_divisor = 3; |
word GC_free_space_divisor = 3; |
|
word GC_free_space_numerator = 1; |
|
|
extern GC_bool GC_collection_in_progress(); |
extern GC_bool GC_collection_in_progress(); |
/* Collection is in progress, or was abandoned. */ |
/* Collection is in progress, or was abandoned. */ |
Line 159 static word min_words_allocd() |
|
Line 167 static word min_words_allocd() |
|
/* use a bit more of large empty heap */ |
/* use a bit more of large empty heap */ |
+ total_root_size); |
+ total_root_size); |
if (TRUE_INCREMENTAL) { |
if (TRUE_INCREMENTAL) { |
return scan_size / (2 * GC_free_space_divisor); |
return scan_size * GC_free_space_numerator / (2 * GC_free_space_divisor); |
} else { |
} else { |
return scan_size / GC_free_space_divisor; |
return scan_size * GC_free_space_numerator / GC_free_space_divisor; |
} |
} |
} |
} |
|
|
Line 249 void GC_maybe_gc() |
|
Line 257 void GC_maybe_gc() |
|
|
|
if (GC_should_collect()) { |
if (GC_should_collect()) { |
if (!GC_incremental) { |
if (!GC_incremental) { |
GC_notify_full_gc(); |
|
GC_gcollect_inner(); |
GC_gcollect_inner(); |
n_partial_gcs = 0; |
n_partial_gcs = 0; |
return; |
return; |
Line 301 void GC_maybe_gc() |
|
Line 308 void GC_maybe_gc() |
|
/* |
/* |
* Stop the world garbage collection. Assumes lock held, signals disabled. |
* Stop the world garbage collection. Assumes lock held, signals disabled. |
* If stop_func is not GC_never_stop_func, then abort if stop_func returns TRUE. |
* If stop_func is not GC_never_stop_func, then abort if stop_func returns TRUE. |
|
* Return TRUE if we successfully completed the collection. |
*/ |
*/ |
GC_bool GC_try_to_collect_inner(stop_func) |
GC_bool GC_try_to_collect_inner(stop_func) |
GC_stop_func stop_func; |
GC_stop_func stop_func; |
Line 308 GC_stop_func stop_func; |
|
Line 316 GC_stop_func stop_func; |
|
# ifdef CONDPRINT |
# ifdef CONDPRINT |
CLOCK_TYPE start_time, current_time; |
CLOCK_TYPE start_time, current_time; |
# endif |
# endif |
|
if (GC_dont_gc) return FALSE; |
if (GC_incremental && GC_collection_in_progress()) { |
if (GC_incremental && GC_collection_in_progress()) { |
# ifdef CONDPRINT |
# ifdef CONDPRINT |
if (GC_print_stats) { |
if (GC_print_stats) { |
Line 321 GC_stop_func stop_func; |
|
Line 330 GC_stop_func stop_func; |
|
GC_collect_a_little_inner(1); |
GC_collect_a_little_inner(1); |
} |
} |
} |
} |
|
if (stop_func == GC_never_stop_func) GC_notify_full_gc(); |
# ifdef CONDPRINT |
# ifdef CONDPRINT |
if (GC_print_stats) { |
if (GC_print_stats) { |
if (GC_print_stats) GET_TIME(start_time); |
if (GC_print_stats) GET_TIME(start_time); |
|
|
{ |
{ |
register int i; |
register int i; |
|
|
|
if (GC_dont_gc) return; |
if (GC_incremental && GC_collection_in_progress()) { |
if (GC_incremental && GC_collection_in_progress()) { |
for (i = GC_deficit; i < GC_RATE*n; i++) { |
for (i = GC_deficit; i < GC_RATE*n; i++) { |
if (GC_mark_some((ptr_t)0)) { |
if (GC_mark_some((ptr_t)0)) { |
Line 463 GC_stop_func stop_func; |
|
Line 474 GC_stop_func stop_func; |
|
# if defined(CONDPRINT) && !defined(PRINTTIMES) |
# if defined(CONDPRINT) && !defined(PRINTTIMES) |
if (GC_print_stats) GET_TIME(start_time); |
if (GC_print_stats) GET_TIME(start_time); |
# endif |
# endif |
|
# if defined(REGISTER_LIBRARIES_EARLY) |
|
GC_cond_register_dynamic_libraries(); |
|
# endif |
|
GC_timerstart(); |
STOP_WORLD(); |
STOP_WORLD(); |
|
IF_THREADS(GC_world_stopped = TRUE); |
# ifdef CONDPRINT |
# ifdef CONDPRINT |
if (GC_print_stats) { |
if (GC_print_stats) { |
GC_printf1("--> Marking for collection %lu ", |
GC_printf1("--> Marking for collection %lu ", |
Line 494 GC_stop_func stop_func; |
|
Line 510 GC_stop_func stop_func; |
|
} |
} |
# endif |
# endif |
GC_deficit = i; /* Give the mutator a chance. */ |
GC_deficit = i; /* Give the mutator a chance. */ |
|
IF_THREADS(GC_world_stopped = FALSE); |
START_WORLD(); |
START_WORLD(); |
|
GC_timerstop(); |
return(FALSE); |
return(FALSE); |
} |
} |
if (GC_mark_some((ptr_t)(&dummy))) break; |
if (GC_mark_some((ptr_t)(&dummy))) break; |
Line 527 GC_stop_func stop_func; |
|
Line 545 GC_stop_func stop_func; |
|
(*GC_check_heap)(); |
(*GC_check_heap)(); |
} |
} |
|
|
|
IF_THREADS(GC_world_stopped = FALSE); |
START_WORLD(); |
START_WORLD(); |
|
GC_timerstop(); |
# ifdef PRINTTIMES |
# ifdef PRINTTIMES |
GET_TIME(current_time); |
GET_TIME(current_time); |
GC_printf1("World-stopped marking took %lu msecs\n", |
GC_printf1("World-stopped marking took %lu msecs\n", |
Line 608 void GC_finish_collection() |
|
Line 628 void GC_finish_collection() |
|
GET_TIME(start_time); |
GET_TIME(start_time); |
finalize_time = start_time; |
finalize_time = start_time; |
# endif |
# endif |
|
GC_timerstart(); |
|
|
# ifdef GATHERSTATS |
# ifdef GATHERSTATS |
GC_mem_found = 0; |
GC_mem_found = 0; |
Line 617 void GC_finish_collection() |
|
Line 638 void GC_finish_collection() |
|
GC_print_address_map(); |
GC_print_address_map(); |
} |
} |
# endif |
# endif |
|
COND_DUMP; |
if (GC_find_leak) { |
if (GC_find_leak) { |
/* Mark all objects on the free list. All objects should be */ |
/* Mark all objects on the free list. All objects should be */ |
/* marked when we're done. */ |
/* marked when we're done. */ |
Line 724 void GC_finish_collection() |
|
Line 746 void GC_finish_collection() |
|
MS_TIME_DIFF(finalize_time,start_time), |
MS_TIME_DIFF(finalize_time,start_time), |
MS_TIME_DIFF(done_time,finalize_time)); |
MS_TIME_DIFF(done_time,finalize_time)); |
# endif |
# endif |
|
GC_timerstop(); |
} |
} |
|
|
/* Externally callable routine to invoke full, stop-world collection */ |
/* Externally callable routine to invoke full, stop-world collection */ |
Line 758 void GC_finish_collection() |
|
Line 781 void GC_finish_collection() |
|
|
|
void GC_gcollect GC_PROTO(()) |
void GC_gcollect GC_PROTO(()) |
{ |
{ |
GC_notify_full_gc(); |
|
(void)GC_try_to_collect(GC_never_stop_func); |
(void)GC_try_to_collect(GC_never_stop_func); |
|
if (GC_have_errors) GC_print_all_errors(); |
} |
} |
|
|
word GC_n_heap_sects = 0; /* Number of sections currently in heap. */ |
word GC_n_heap_sects = 0; /* Number of sections currently in heap. */ |
|
|
GC_prev_heap_addr = GC_last_heap_addr; |
GC_prev_heap_addr = GC_last_heap_addr; |
GC_last_heap_addr = (ptr_t)space; |
GC_last_heap_addr = (ptr_t)space; |
GC_add_to_heap(space, bytes); |
GC_add_to_heap(space, bytes); |
|
#if defined(VISUAL) |
|
SendHeapSize(); |
|
#endif |
return(TRUE); |
return(TRUE); |
} |
} |
|
|
Line 961 GC_bool ignore_off_page; |
|
Line 987 GC_bool ignore_off_page; |
|
{ |
{ |
if (!GC_incremental && !GC_dont_gc && |
if (!GC_incremental && !GC_dont_gc && |
(GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) { |
(GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) { |
GC_notify_full_gc(); |
|
GC_gcollect_inner(); |
GC_gcollect_inner(); |
} else { |
} else { |
word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor) |
word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor) |
Line 986 GC_bool ignore_off_page; |
|
Line 1011 GC_bool ignore_off_page; |
|
&& !GC_expand_hp_inner(needed_blocks)) { |
&& !GC_expand_hp_inner(needed_blocks)) { |
if (GC_fail_count++ < GC_max_retries) { |
if (GC_fail_count++ < GC_max_retries) { |
WARN("Out of Memory! Trying to continue ...\n", 0); |
WARN("Out of Memory! Trying to continue ...\n", 0); |
GC_notify_full_gc(); |
|
GC_gcollect_inner(); |
GC_gcollect_inner(); |
} else { |
} else { |
# if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC) |
# if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC) |
|
|
|
|
if (sz == 0) return(0); |
if (sz == 0) return(0); |
|
|
|
#if defined(VISUAL) |
|
{ |
|
#include <signal.h> |
|
extern int recv_intr; |
|
if ( recv_intr ) { |
|
if ( recv_intr == 1 ) { |
|
recv_intr = 0; |
|
int_handler(); |
|
} else { |
|
recv_intr = 0; |
|
ox_usr1_handler(0); |
|
} |
|
} |
|
} |
|
#endif |
while (*flh == 0) { |
while (*flh == 0) { |
ENTER_GC(); |
ENTER_GC(); |
/* Do our share of marking work */ |
/* Do our share of marking work */ |
if(TRUE_INCREMENTAL && !GC_dont_gc) GC_collect_a_little_inner(1); |
if(TRUE_INCREMENTAL) GC_collect_a_little_inner(1); |
/* Sweep blocks for objects of this size */ |
/* Sweep blocks for objects of this size */ |
GC_continue_reclaim(sz, kind); |
GC_continue_reclaim(sz, kind); |
EXIT_GC(); |
EXIT_GC(); |
|
|
EXIT_GC(); |
EXIT_GC(); |
} |
} |
} |
} |
|
/* Successful allocation; reset failure count. */ |
|
GC_fail_count = 0; |
|
|
return(*flh); |
return(*flh); |
} |
} |