97
104
extern GC_bool GC_collection_in_progress();
98
105
/* Collection is in progress, or was abandoned. */
100
extern GC_bool GC_print_back_height;
102
107
int GC_never_stop_func GC_PROTO((void)) { return(0); }
104
109
unsigned long GC_time_limit = TIME_LIMIT;
126
131
if (GC_print_stats) {
127
132
GC_printf0("Abandoning stopped marking after ");
128
133
GC_printf1("%lu msecs", (unsigned long)time_diff);
129
GC_printf1("(attempt %d)\n", (unsigned long) GC_n_attempts);
134
GC_printf1("(attempt %ld)\n", (unsigned long) GC_n_attempts);
180
185
/* managed object should not alter result, assuming the client */
181
186
/* is playing by the rules. */
182
187
result = (signed_word)GC_words_allocd
183
- (signed_word)GC_mem_freed - expl_managed;
188
- (signed_word)GC_mem_freed
189
+ (signed_word)GC_finalizer_mem_freed - expl_managed;
184
190
if (result > (signed_word)GC_words_allocd) {
185
191
result = GC_words_allocd;
186
192
/* probably client bug or unfortunate scheduling */
190
196
/* had been reallocated this round. Finalization is user */
191
197
/* visible progress. And if we don't count this, we have */
192
198
/* stability problems for programs that finalize all objects. */
193
result += GC_words_wasted;
199
if ((GC_words_wasted >> 3) < result)
200
result += GC_words_wasted;
194
201
/* This doesn't reflect useful work. But if there is lots of */
195
202
/* new fragmentation, the same is probably true of the heap, */
196
203
/* and the collection will be correspondingly cheaper. */
220
227
for (i = 0; i < NWORDS; i++) frames[i] = 0;
230
/* Heap size at which we need a collection to avoid expanding past */
231
/* limits used by blacklisting. */
232
static word GC_collect_at_heapsize = (word)(-1);
223
234
/* Have we allocated enough to amortize a collection? */
224
235
GC_bool GC_should_collect()
226
return(GC_adj_words_allocd() >= min_words_allocd());
237
return(GC_adj_words_allocd() >= min_words_allocd()
238
|| GC_heapsize >= GC_collect_at_heapsize);
301
312
* Stop the world garbage collection. Assumes lock held, signals disabled.
302
313
* If stop_func is not GC_never_stop_func, then abort if stop_func returns TRUE.
314
* Return TRUE if we successfully completed the collection.
304
316
GC_bool GC_try_to_collect_inner(stop_func)
305
317
GC_stop_func stop_func;
320
CLOCK_TYPE start_time, current_time;
322
if (GC_dont_gc) return FALSE;
307
323
if (GC_incremental && GC_collection_in_progress()) {
308
324
# ifdef CONDPRINT
309
325
if (GC_print_stats) {
317
333
GC_collect_a_little_inner(1);
336
if (stop_func == GC_never_stop_func) GC_notify_full_gc();
320
337
# ifdef CONDPRINT
321
338
if (GC_print_stats) {
339
if (GC_print_stats) GET_TIME(start_time);
323
341
"Initiating full world-stop collection %lu after %ld allocd bytes\n",
324
342
(unsigned long) GC_gc_no+1,
444
471
CLOCK_TYPE start_time, current_time;
448
474
# ifdef PRINTTIMES
449
475
GET_TIME(start_time);
451
477
# if defined(CONDPRINT) && !defined(PRINTTIMES)
452
478
if (GC_print_stats) GET_TIME(start_time);
480
# if defined(REGISTER_LIBRARIES_EARLY)
481
GC_cond_register_dynamic_libraries();
484
IF_THREADS(GC_world_stopped = TRUE);
454
485
# ifdef CONDPRINT
455
486
if (GC_print_stats) {
456
487
GC_printf1("--> Marking for collection %lu ",
736
772
ENABLE_SIGNALS();
737
if(result) GC_INVOKE_FINALIZERS();
774
if (GC_debugging_started) GC_print_all_smashed();
775
GC_INVOKE_FINALIZERS();
741
780
void GC_gcollect GC_PROTO(())
744
782
(void)GC_try_to_collect(GC_never_stop_func);
783
if (GC_have_errors) GC_print_all_errors();
747
786
word GC_n_heap_sects = 0; /* Number of sections currently in heap. */
892
expansion_slop = 8 * WORDS_TO_BYTES(min_words_allocd());
893
if (5 * HBLKSIZE * MAXHINCR > expansion_slop) {
894
expansion_slop = 5 * HBLKSIZE * MAXHINCR;
931
expansion_slop = WORDS_TO_BYTES(min_words_allocd()) + 4*MAXHINCR*HBLKSIZE;
896
932
if (GC_last_heap_addr == 0 && !((word)space & SIGNB)
897
|| GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space) {
933
|| (GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space)) {
898
934
/* Assume the heap is growing up */
899
935
GC_greatest_plausible_heap_addr =
900
GC_max(GC_greatest_plausible_heap_addr,
901
(ptr_t)space + bytes + expansion_slop);
936
(GC_PTR)GC_max((ptr_t)GC_greatest_plausible_heap_addr,
937
(ptr_t)space + bytes + expansion_slop);
903
939
/* Heap is growing down */
904
940
GC_least_plausible_heap_addr =
905
GC_min(GC_least_plausible_heap_addr,
906
(ptr_t)space - expansion_slop);
941
(GC_PTR)GC_min((ptr_t)GC_least_plausible_heap_addr,
942
(ptr_t)space - expansion_slop);
944
# if defined(LARGE_CONFIG)
945
if (((ptr_t)GC_greatest_plausible_heap_addr <= (ptr_t)space + bytes
946
|| (ptr_t)GC_least_plausible_heap_addr >= (ptr_t)space)
947
&& GC_heapsize > 0) {
948
/* GC_add_to_heap will fix this, but ... */
949
WARN("Too close to address space limit: blacklisting ineffective\n", 0);
908
952
GC_prev_heap_addr = GC_last_heap_addr;
909
953
GC_last_heap_addr = (ptr_t)space;
910
954
GC_add_to_heap(space, bytes);
955
/* Force GC before we are likely to allocate past expansion_slop */
956
GC_collect_at_heapsize =
957
GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE;
958
# if defined(LARGE_CONFIG)
959
if (GC_collect_at_heapsize < GC_heapsize /* wrapped */)
960
GC_collect_at_heapsize = (word)(-1);
942
993
GC_bool ignore_off_page;
944
995
if (!GC_incremental && !GC_dont_gc &&
945
(GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) {
996
((GC_dont_expand && GC_words_allocd > 0) || GC_should_collect())) {
947
997
GC_gcollect_inner();
949
999
word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)
952
1002
if (blocks_to_get > MAXHINCR) {
1005
/* Get the minimum required to make it likely that we */
1006
/* can satisfy the current request in the presence of black- */
1007
/* listing. This will probably be more than MAXHINCR. */
955
1008
if (ignore_off_page) {
968
1021
&& !GC_expand_hp_inner(needed_blocks)) {
969
1022
if (GC_fail_count++ < GC_max_retries) {
970
1023
WARN("Out of Memory! Trying to continue ...\n", 0);
972
1024
GC_gcollect_inner();
974
1026
# if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC)
1006
1058
while (*flh == 0) {
1008
1060
/* Do our share of marking work */
1009
if(TRUE_INCREMENTAL && !GC_dont_gc) GC_collect_a_little_inner(1);
1061
if(TRUE_INCREMENTAL) GC_collect_a_little_inner(1);
1010
1062
/* Sweep blocks for objects of this size */
1011
1063
GC_continue_reclaim(sz, kind);