~ubuntu-branches/ubuntu/hardy/libgc/hardy-updates

« back to all changes in this revision

Viewing changes to alloc.c

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Murray
  • Date: 2005-02-03 00:50:53 UTC
  • mto: (3.1.1 etch) (1.2.4 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20050203005053-9c0v9r2qcm2g1cfp
Tags: upstream-6.4
ImportĀ upstreamĀ versionĀ 6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
GC_bool GC_need_full_gc = FALSE;
73
73
                           /* Need full GC do to heap growth.   */
74
74
 
 
75
#ifdef THREADS
 
76
  GC_bool GC_world_stopped = FALSE;
 
77
# define IF_THREADS(x) x
 
78
#else
 
79
# define IF_THREADS(x)
 
80
#endif
 
81
 
75
82
word GC_used_heap_size_after_full = 0;
76
83
 
77
84
char * GC_copyright[] =
97
104
extern GC_bool GC_collection_in_progress();
98
105
                /* Collection is in progress, or was abandoned. */
99
106
 
100
 
extern GC_bool GC_print_back_height;
101
 
 
102
107
int GC_never_stop_func GC_PROTO((void)) { return(0); }
103
108
 
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);
130
135
          }
131
136
#       endif
132
137
        return(1);
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;
221
228
}
222
229
 
 
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);
 
233
 
223
234
/* Have we allocated enough to amortize a collection? */
224
235
GC_bool GC_should_collect()
225
236
{
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);
227
239
}
228
240
 
229
241
 
248
260
 
249
261
    if (GC_should_collect()) {
250
262
        if (!GC_incremental) {
251
 
            GC_notify_full_gc();
252
263
            GC_gcollect_inner();
253
264
            n_partial_gcs = 0;
254
265
            return;
300
311
/*
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.
303
315
 */
304
316
GC_bool GC_try_to_collect_inner(stop_func)
305
317
GC_stop_func stop_func;
306
318
{
 
319
#   ifdef CONDPRINT
 
320
        CLOCK_TYPE start_time, current_time;
 
321
#   endif
 
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);
318
334
        }
319
335
    }
 
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);
322
340
        GC_printf2(
323
341
           "Initiating full world-stop collection %lu after %ld allocd bytes\n",
324
342
           (unsigned long) GC_gc_no+1,
357
375
      return(FALSE);
358
376
    }
359
377
    GC_finish_collection();
 
378
#   if defined(CONDPRINT)
 
379
      if (GC_print_stats) {
 
380
        GET_TIME(current_time);
 
381
        GC_printf1("Complete collection took %lu msecs\n",
 
382
                   MS_TIME_DIFF(current_time,start_time));
 
383
      }
 
384
#   endif
360
385
    return(TRUE);
361
386
}
362
387
 
384
409
{
385
410
    register int i;
386
411
    
 
412
    if (GC_dont_gc) return;
387
413
    if (GC_incremental && GC_collection_in_progress()) {
388
414
        for (i = GC_deficit; i < GC_RATE*n; i++) {
389
415
            if (GC_mark_some((ptr_t)0)) {
426
452
    result = (int)GC_collection_in_progress();
427
453
    UNLOCK();
428
454
    ENABLE_SIGNALS();
 
455
    if (!result && GC_debugging_started) GC_print_all_smashed();
429
456
    return(result);
430
457
}
431
458
 
444
471
        CLOCK_TYPE start_time, current_time;
445
472
#   endif
446
473
        
447
 
    STOP_WORLD();
448
474
#   ifdef PRINTTIMES
449
475
        GET_TIME(start_time);
450
476
#   endif
451
477
#   if defined(CONDPRINT) && !defined(PRINTTIMES)
452
478
        if (GC_print_stats) GET_TIME(start_time);
453
479
#   endif
 
480
#   if defined(REGISTER_LIBRARIES_EARLY)
 
481
        GC_cond_register_dynamic_libraries();
 
482
#   endif
 
483
    STOP_WORLD();
 
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 ",
481
512
                      }
482
513
#                   endif
483
514
                    GC_deficit = i; /* Give the mutator a chance. */
 
515
                    IF_THREADS(GC_world_stopped = FALSE);
484
516
                    START_WORLD();
485
517
                    return(FALSE);
486
518
            }
514
546
            (*GC_check_heap)();
515
547
        }
516
548
    
 
549
    IF_THREADS(GC_world_stopped = FALSE);
 
550
    START_WORLD();
517
551
#   ifdef PRINTTIMES
518
552
        GET_TIME(current_time);
519
553
        GC_printf1("World-stopped marking took %lu msecs\n",
527
561
        }
528
562
#     endif
529
563
#   endif
530
 
    START_WORLD();
531
564
    return(TRUE);
532
565
}
533
566
 
604
637
          GC_print_address_map();
605
638
        }
606
639
#   endif
 
640
    COND_DUMP;
607
641
    if (GC_find_leak) {
608
642
      /* Mark all objects on the free list.  All objects should be */
609
643
      /* marked when we're done.                                   */
700
734
      GC_words_allocd = 0;
701
735
      GC_words_wasted = 0;
702
736
      GC_mem_freed = 0;
 
737
      GC_finalizer_mem_freed = 0;
703
738
      
704
739
#   ifdef USE_MUNMAP
705
740
      GC_unmap_old();
723
758
    int result;
724
759
    DCL_LOCK_STATE;
725
760
    
 
761
    if (GC_debugging_started) GC_print_all_smashed();
726
762
    GC_INVOKE_FINALIZERS();
727
763
    DISABLE_SIGNALS();
728
764
    LOCK();
734
770
    EXIT_GC();
735
771
    UNLOCK();
736
772
    ENABLE_SIGNALS();
737
 
    if(result) GC_INVOKE_FINALIZERS();
 
773
    if(result) {
 
774
        if (GC_debugging_started) GC_print_all_smashed();
 
775
        GC_INVOKE_FINALIZERS();
 
776
    }
738
777
    return(result);
739
778
}
740
779
 
741
780
void GC_gcollect GC_PROTO(())
742
781
{
743
 
    GC_notify_full_gc();
744
782
    (void)GC_try_to_collect(GC_never_stop_func);
 
783
    if (GC_have_errors) GC_print_all_errors();
745
784
}
746
785
 
747
786
word GC_n_heap_sects = 0;       /* Number of sections currently in heap. */
889
928
#       endif
890
929
      }
891
930
#   endif
892
 
    expansion_slop = 8 * WORDS_TO_BYTES(min_words_allocd());
893
 
    if (5 * HBLKSIZE * MAXHINCR > expansion_slop) {
894
 
        expansion_slop = 5 * HBLKSIZE * MAXHINCR;
895
 
    }
 
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);
902
938
    } else {
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);
907
943
    }
 
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);
 
950
      }
 
951
#   endif
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);
 
961
#     endif
911
962
    return(TRUE);
912
963
}
913
964
 
942
993
GC_bool ignore_off_page;
943
994
{
944
995
    if (!GC_incremental && !GC_dont_gc &&
945
 
        (GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) {
946
 
      GC_notify_full_gc();
 
996
        ((GC_dont_expand && GC_words_allocd > 0) || GC_should_collect())) {
947
997
      GC_gcollect_inner();
948
998
    } else {
949
999
      word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)
952
1002
      if (blocks_to_get > MAXHINCR) {
953
1003
          word slop;
954
1004
          
 
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) {
956
1009
              slop = 4;
957
1010
          } else {
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);
971
 
            GC_notify_full_gc();
972
1024
            GC_gcollect_inner();
973
1025
        } else {
974
1026
#           if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC)
1006
1058
    while (*flh == 0) {
1007
1059
      ENTER_GC();
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);
1012
1064
      EXIT_GC();
1028
1080
        EXIT_GC();
1029
1081
      }
1030
1082
    }
 
1083
    /* Successful allocation; reset failure count.      */
 
1084
    GC_fail_count = 0;
1031
1085
    
1032
1086
    return(*flh);
1033
1087
}