[BACK]Return to reclaim.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc

Annotation of OpenXM_contrib2/asir2000/gc/reclaim.c, Revision 1.1.1.1

1.1       noro        1: /*
                      2:  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
                      3:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
                      4:  *
                      5:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      6:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      7:  *
                      8:  * Permission is hereby granted to use or copy this program
                      9:  * for any purpose,  provided the above notices are retained on all copies.
                     10:  * Permission to modify the code and to distribute modified code is granted,
                     11:  * provided the above notices are retained, and a notice that the code was
                     12:  * modified is included with the above copyright notice.
                     13:  */
                     14: /* Boehm, February 15, 1996 2:41 pm PST */
                     15:
                     16: #include <stdio.h>
                     17: #include "gc_priv.h"
                     18:
                     19: void GC_timerstart(), GC_timerstop();
                     20:
                     21: signed_word GC_mem_found = 0;
                     22:                        /* Number of words of memory reclaimed     */
                     23:
                     24: # ifdef FIND_LEAK
                     25: static void report_leak(p, sz)
                     26: ptr_t p;
                     27: word sz;
                     28: {
                     29:     if (HDR(p) -> hb_obj_kind == PTRFREE) {
                     30:         GC_err_printf0("Leaked atomic object at ");
                     31:     } else {
                     32:         GC_err_printf0("Leaked composite object at ");
                     33:     }
                     34:     if (GC_debugging_started && GC_has_debug_info(p)) {
                     35:         GC_print_obj(p);
                     36:     } else {
                     37:         GC_err_printf2("0x%lx (appr. size = %ld)\n",
                     38:                              (unsigned long)p,
                     39:                              (unsigned long)WORDS_TO_BYTES(sz));
                     40:     }
                     41: }
                     42:
                     43: #   define FOUND_FREE(hblk, word_no) \
                     44:       if (abort_if_found) { \
                     45:          report_leak((ptr_t)hblk + WORDS_TO_BYTES(word_no), \
                     46:                     HDR(hblk) -> hb_sz); \
                     47:       }
                     48: # else
                     49: #   define FOUND_FREE(hblk, word_no)
                     50: # endif
                     51:
                     52: /*
                     53:  * reclaim phase
                     54:  *
                     55:  */
                     56:
                     57:
                     58: /*
                     59:  * Test whether a block is completely empty, i.e. contains no marked
                     60:  * objects.  This does not require the block to be in physical
                     61:  * memory.
                     62:  */
                     63:
                     64: GC_bool GC_block_empty(hhdr)
                     65: register hdr * hhdr;
                     66: {
                     67:     register word *p = (word *)(&(hhdr -> hb_marks[0]));
                     68:     register word * plim =
                     69:                        (word *)(&(hhdr -> hb_marks[MARK_BITS_SZ]));
                     70:     while (p < plim) {
                     71:        if (*p++) return(FALSE);
                     72:     }
                     73:     return(TRUE);
                     74: }
                     75:
                     76: # ifdef GATHERSTATS
                     77: #   define INCR_WORDS(sz) n_words_found += (sz)
                     78: # else
                     79: #   define INCR_WORDS(sz)
                     80: # endif
                     81: /*
                     82:  * Restore unmarked small objects in h of size sz to the object
                     83:  * free list.  Returns the new list.
                     84:  * Clears unmarked objects.
                     85:  */
                     86: /*ARGSUSED*/
                     87: ptr_t GC_reclaim_clear(hbp, hhdr, sz, list, abort_if_found)
                     88: register struct hblk *hbp;     /* ptr to current heap block            */
                     89: register hdr * hhdr;
                     90: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                     91: register ptr_t list;
                     92: register word sz;
                     93: {
                     94:     register int word_no;
                     95:     register word *p, *q, *plim;
                     96: #   ifdef GATHERSTATS
                     97:         register int n_words_found = 0;
                     98: #   endif
                     99:
                    100:     p = (word *)(hbp->hb_body);
                    101:     word_no = HDR_WORDS;
                    102:     plim = (word *)((((word)hbp) + HBLKSIZE)
                    103:                   - WORDS_TO_BYTES(sz));
                    104:
                    105:     /* go through all words in block */
                    106:        while( p <= plim )  {
                    107:            if( mark_bit_from_hdr(hhdr, word_no) ) {
                    108:                p += sz;
                    109:            } else {
                    110:                FOUND_FREE(hbp, word_no);
                    111:                INCR_WORDS(sz);
                    112:                /* object is available - put on list */
                    113:                    obj_link(p) = list;
                    114:                    list = ((ptr_t)p);
                    115:                /* Clear object, advance p to next object in the process */
                    116:                    q = p + sz;
                    117:                     p++; /* Skip link field */
                    118:                     while (p < q) {
                    119:                        *p++ = 0;
                    120:                    }
                    121:            }
                    122:            word_no += sz;
                    123:        }
                    124: #   ifdef GATHERSTATS
                    125:        GC_mem_found += n_words_found;
                    126: #   endif
                    127:     return(list);
                    128: }
                    129:
                    130: #ifndef SMALL_CONFIG
                    131:
                    132: /*
                    133:  * A special case for 2 word composite objects (e.g. cons cells):
                    134:  */
                    135: /*ARGSUSED*/
                    136: ptr_t GC_reclaim_clear2(hbp, hhdr, list, abort_if_found)
                    137: register struct hblk *hbp;     /* ptr to current heap block            */
                    138: hdr * hhdr;
                    139: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                    140: register ptr_t list;
                    141: {
                    142:     register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
                    143:     register word *p, *plim;
                    144: #   ifdef GATHERSTATS
                    145:         register int n_words_found = 0;
                    146: #   endif
                    147:     register word mark_word;
                    148:     register int i;
                    149: #   define DO_OBJ(start_displ) \
                    150:        if (!(mark_word & ((word)1 << start_displ))) { \
                    151:            FOUND_FREE(hbp, p - (word *)hbp + start_displ); \
                    152:            p[start_displ] = (word)list; \
                    153:            list = (ptr_t)(p+start_displ); \
                    154:            p[start_displ+1] = 0; \
                    155:            INCR_WORDS(2); \
                    156:        }
                    157:
                    158:     p = (word *)(hbp->hb_body);
                    159:     plim = (word *)(((word)hbp) + HBLKSIZE);
                    160:
                    161:     /* go through all words in block */
                    162:        while( p < plim )  {
                    163:            mark_word = *mark_word_addr++;
                    164:            for (i = 0; i < WORDSZ; i += 8) {
                    165:                DO_OBJ(0);
                    166:                DO_OBJ(2);
                    167:                DO_OBJ(4);
                    168:                DO_OBJ(6);
                    169:                p += 8;
                    170:                mark_word >>= 8;
                    171:            }
                    172:        }
                    173: #   ifdef GATHERSTATS
                    174:        GC_mem_found += n_words_found;
                    175: #   endif
                    176:     return(list);
                    177: #   undef DO_OBJ
                    178: }
                    179:
                    180: /*
                    181:  * Another special case for 4 word composite objects:
                    182:  */
                    183: /*ARGSUSED*/
                    184: ptr_t GC_reclaim_clear4(hbp, hhdr, list, abort_if_found)
                    185: register struct hblk *hbp;     /* ptr to current heap block            */
                    186: hdr * hhdr;
                    187: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                    188: register ptr_t list;
                    189: {
                    190:     register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
                    191:     register word *p, *plim;
                    192: #   ifdef GATHERSTATS
                    193:         register int n_words_found = 0;
                    194: #   endif
                    195:     register word mark_word;
                    196: #   define DO_OBJ(start_displ) \
                    197:        if (!(mark_word & ((word)1 << start_displ))) { \
                    198:            FOUND_FREE(hbp, p - (word *)hbp + start_displ); \
                    199:            p[start_displ] = (word)list; \
                    200:            list = (ptr_t)(p+start_displ); \
                    201:            p[start_displ+1] = 0; \
                    202:            p[start_displ+2] = 0; \
                    203:            p[start_displ+3] = 0; \
                    204:            INCR_WORDS(4); \
                    205:        }
                    206:
                    207:     p = (word *)(hbp->hb_body);
                    208:     plim = (word *)(((word)hbp) + HBLKSIZE);
                    209:
                    210:     /* go through all words in block */
                    211:        while( p < plim )  {
                    212:            mark_word = *mark_word_addr++;
                    213:            DO_OBJ(0);
                    214:            DO_OBJ(4);
                    215:            DO_OBJ(8);
                    216:            DO_OBJ(12);
                    217:            DO_OBJ(16);
                    218:            DO_OBJ(20);
                    219:            DO_OBJ(24);
                    220:            DO_OBJ(28);
                    221: #          if CPP_WORDSZ == 64
                    222:              DO_OBJ(32);
                    223:              DO_OBJ(36);
                    224:              DO_OBJ(40);
                    225:              DO_OBJ(44);
                    226:              DO_OBJ(48);
                    227:              DO_OBJ(52);
                    228:              DO_OBJ(56);
                    229:              DO_OBJ(60);
                    230: #          endif
                    231:            p += WORDSZ;
                    232:        }
                    233: #   ifdef GATHERSTATS
                    234:        GC_mem_found += n_words_found;
                    235: #   endif
                    236:     return(list);
                    237: #   undef DO_OBJ
                    238: }
                    239:
                    240: #endif /* !SMALL_CONFIG */
                    241:
                    242: /* The same thing, but don't clear objects: */
                    243: /*ARGSUSED*/
                    244: ptr_t GC_reclaim_uninit(hbp, hhdr, sz, list, abort_if_found)
                    245: register struct hblk *hbp;     /* ptr to current heap block            */
                    246: register hdr * hhdr;
                    247: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                    248: register ptr_t list;
                    249: register word sz;
                    250: {
                    251:     register int word_no;
                    252:     register word *p, *plim;
                    253: #   ifdef GATHERSTATS
                    254:         register int n_words_found = 0;
                    255: #   endif
                    256:
                    257:     p = (word *)(hbp->hb_body);
                    258:     word_no = HDR_WORDS;
                    259:     plim = (word *)((((word)hbp) + HBLKSIZE)
                    260:                   - WORDS_TO_BYTES(sz));
                    261:
                    262:     /* go through all words in block */
                    263:        while( p <= plim )  {
                    264:            if( !mark_bit_from_hdr(hhdr, word_no) ) {
                    265:                FOUND_FREE(hbp, word_no);
                    266:                INCR_WORDS(sz);
                    267:                /* object is available - put on list */
                    268:                    obj_link(p) = list;
                    269:                    list = ((ptr_t)p);
                    270:            }
                    271:            p += sz;
                    272:            word_no += sz;
                    273:        }
                    274: #   ifdef GATHERSTATS
                    275:        GC_mem_found += n_words_found;
                    276: #   endif
                    277:     return(list);
                    278: }
                    279:
                    280: #ifndef SMALL_CONFIG
                    281: /*
                    282:  * Another special case for 2 word atomic objects:
                    283:  */
                    284: /*ARGSUSED*/
                    285: ptr_t GC_reclaim_uninit2(hbp, hhdr, list, abort_if_found)
                    286: register struct hblk *hbp;     /* ptr to current heap block            */
                    287: hdr * hhdr;
                    288: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                    289: register ptr_t list;
                    290: {
                    291:     register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
                    292:     register word *p, *plim;
                    293: #   ifdef GATHERSTATS
                    294:         register int n_words_found = 0;
                    295: #   endif
                    296:     register word mark_word;
                    297:     register int i;
                    298: #   define DO_OBJ(start_displ) \
                    299:        if (!(mark_word & ((word)1 << start_displ))) { \
                    300:            FOUND_FREE(hbp, p - (word *)hbp + start_displ); \
                    301:            p[start_displ] = (word)list; \
                    302:            list = (ptr_t)(p+start_displ); \
                    303:            INCR_WORDS(2); \
                    304:        }
                    305:
                    306:     p = (word *)(hbp->hb_body);
                    307:     plim = (word *)(((word)hbp) + HBLKSIZE);
                    308:
                    309:     /* go through all words in block */
                    310:        while( p < plim )  {
                    311:            mark_word = *mark_word_addr++;
                    312:            for (i = 0; i < WORDSZ; i += 8) {
                    313:                DO_OBJ(0);
                    314:                DO_OBJ(2);
                    315:                DO_OBJ(4);
                    316:                DO_OBJ(6);
                    317:                p += 8;
                    318:                mark_word >>= 8;
                    319:            }
                    320:        }
                    321: #   ifdef GATHERSTATS
                    322:        GC_mem_found += n_words_found;
                    323: #   endif
                    324:     return(list);
                    325: #   undef DO_OBJ
                    326: }
                    327:
                    328: /*
                    329:  * Another special case for 4 word atomic objects:
                    330:  */
                    331: /*ARGSUSED*/
                    332: ptr_t GC_reclaim_uninit4(hbp, hhdr, list, abort_if_found)
                    333: register struct hblk *hbp;     /* ptr to current heap block            */
                    334: hdr * hhdr;
                    335: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                    336: register ptr_t list;
                    337: {
                    338:     register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
                    339:     register word *p, *plim;
                    340: #   ifdef GATHERSTATS
                    341:         register int n_words_found = 0;
                    342: #   endif
                    343:     register word mark_word;
                    344: #   define DO_OBJ(start_displ) \
                    345:        if (!(mark_word & ((word)1 << start_displ))) { \
                    346:            FOUND_FREE(hbp, p - (word *)hbp + start_displ); \
                    347:            p[start_displ] = (word)list; \
                    348:            list = (ptr_t)(p+start_displ); \
                    349:            INCR_WORDS(4); \
                    350:        }
                    351:
                    352:     p = (word *)(hbp->hb_body);
                    353:     plim = (word *)(((word)hbp) + HBLKSIZE);
                    354:
                    355:     /* go through all words in block */
                    356:        while( p < plim )  {
                    357:            mark_word = *mark_word_addr++;
                    358:            DO_OBJ(0);
                    359:            DO_OBJ(4);
                    360:            DO_OBJ(8);
                    361:            DO_OBJ(12);
                    362:            DO_OBJ(16);
                    363:            DO_OBJ(20);
                    364:            DO_OBJ(24);
                    365:            DO_OBJ(28);
                    366: #          if CPP_WORDSZ == 64
                    367:              DO_OBJ(32);
                    368:              DO_OBJ(36);
                    369:              DO_OBJ(40);
                    370:              DO_OBJ(44);
                    371:              DO_OBJ(48);
                    372:              DO_OBJ(52);
                    373:              DO_OBJ(56);
                    374:              DO_OBJ(60);
                    375: #          endif
                    376:            p += WORDSZ;
                    377:        }
                    378: #   ifdef GATHERSTATS
                    379:        GC_mem_found += n_words_found;
                    380: #   endif
                    381:     return(list);
                    382: #   undef DO_OBJ
                    383: }
                    384:
                    385: /* Finally the one word case, which never requires any clearing: */
                    386: /*ARGSUSED*/
                    387: ptr_t GC_reclaim1(hbp, hhdr, list, abort_if_found)
                    388: register struct hblk *hbp;     /* ptr to current heap block            */
                    389: hdr * hhdr;
                    390: GC_bool abort_if_found;                /* Abort if a reclaimable object is found */
                    391: register ptr_t list;
                    392: {
                    393:     register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
                    394:     register word *p, *plim;
                    395: #   ifdef GATHERSTATS
                    396:         register int n_words_found = 0;
                    397: #   endif
                    398:     register word mark_word;
                    399:     register int i;
                    400: #   define DO_OBJ(start_displ) \
                    401:        if (!(mark_word & ((word)1 << start_displ))) { \
                    402:            FOUND_FREE(hbp, p - (word *)hbp + start_displ); \
                    403:            p[start_displ] = (word)list; \
                    404:            list = (ptr_t)(p+start_displ); \
                    405:            INCR_WORDS(1); \
                    406:        }
                    407:
                    408:     p = (word *)(hbp->hb_body);
                    409:     plim = (word *)(((word)hbp) + HBLKSIZE);
                    410:
                    411:     /* go through all words in block */
                    412:        while( p < plim )  {
                    413:            mark_word = *mark_word_addr++;
                    414:            for (i = 0; i < WORDSZ; i += 4) {
                    415:                DO_OBJ(0);
                    416:                DO_OBJ(1);
                    417:                DO_OBJ(2);
                    418:                DO_OBJ(3);
                    419:                p += 4;
                    420:                mark_word >>= 4;
                    421:            }
                    422:        }
                    423: #   ifdef GATHERSTATS
                    424:        GC_mem_found += n_words_found;
                    425: #   endif
                    426:     return(list);
                    427: #   undef DO_OBJ
                    428: }
                    429:
                    430: #endif /* !SMALL_CONFIG */
                    431:
                    432: /*
                    433:  * Restore unmarked small objects in the block pointed to by hbp
                    434:  * to the appropriate object free list.
                    435:  * If entirely empty blocks are to be completely deallocated, then
                    436:  * caller should perform that check.
                    437:  */
                    438: void GC_reclaim_small_nonempty_block(hbp, abort_if_found)
                    439: register struct hblk *hbp;     /* ptr to current heap block            */
                    440: int abort_if_found;            /* Abort if a reclaimable object is found */
                    441: {
                    442:     hdr * hhdr;
                    443:     register word sz;          /* size of objects in current block     */
                    444:     register struct obj_kind * ok;
                    445:     register ptr_t * flh;
                    446:     register int kind;
                    447:
                    448:     hhdr = HDR(hbp);
                    449:     sz = hhdr -> hb_sz;
                    450:     hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no;
                    451:     kind = hhdr -> hb_obj_kind;
                    452:     ok = &GC_obj_kinds[kind];
                    453:     flh = &(ok -> ok_freelist[sz]);
                    454:     GC_write_hint(hbp);
                    455:
                    456:     if (ok -> ok_init) {
                    457:       switch(sz) {
                    458: #      ifndef SMALL_CONFIG
                    459:         case 1:
                    460:             *flh = GC_reclaim1(hbp, hhdr, *flh, abort_if_found);
                    461:             break;
                    462:         case 2:
                    463:             *flh = GC_reclaim_clear2(hbp, hhdr, *flh, abort_if_found);
                    464:             break;
                    465:         case 4:
                    466:             *flh = GC_reclaim_clear4(hbp, hhdr, *flh, abort_if_found);
                    467:             break;
                    468: #      endif
                    469:         default:
                    470:             *flh = GC_reclaim_clear(hbp, hhdr, sz, *flh, abort_if_found);
                    471:             break;
                    472:       }
                    473:     } else {
                    474:       switch(sz) {
                    475: #      ifndef SMALL_CONFIG
                    476:         case 1:
                    477:             *flh = GC_reclaim1(hbp, hhdr, *flh, abort_if_found);
                    478:             break;
                    479:         case 2:
                    480:             *flh = GC_reclaim_uninit2(hbp, hhdr, *flh, abort_if_found);
                    481:             break;
                    482:         case 4:
                    483:             *flh = GC_reclaim_uninit4(hbp, hhdr, *flh, abort_if_found);
                    484:             break;
                    485: #      endif
                    486:         default:
                    487:             *flh = GC_reclaim_uninit(hbp, hhdr, sz, *flh, abort_if_found);
                    488:             break;
                    489:       }
                    490:     }
                    491:     if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(hhdr);
                    492: }
                    493:
                    494: /*
                    495:  * Restore an unmarked large object or an entirely empty blocks of small objects
                    496:  * to the heap block free list.
                    497:  * Otherwise enqueue the block for later processing
                    498:  * by GC_reclaim_small_nonempty_block.
                    499:  * If abort_if_found is TRUE, then process any block immediately.
                    500:  */
                    501: void GC_reclaim_block(hbp, abort_if_found)
                    502: register struct hblk *hbp;     /* ptr to current heap block            */
                    503: word abort_if_found;           /* Abort if a reclaimable object is found */
                    504: {
                    505:     register hdr * hhdr;
                    506:     register word sz;          /* size of objects in current block     */
                    507:     register struct obj_kind * ok;
                    508:     struct hblk ** rlh;
                    509:
                    510:     hhdr = HDR(hbp);
                    511:     sz = hhdr -> hb_sz;
                    512:     ok = &GC_obj_kinds[hhdr -> hb_obj_kind];
                    513:
                    514:     if( sz > MAXOBJSZ ) {  /* 1 big object */
                    515:         if( !mark_bit_from_hdr(hhdr, HDR_WORDS) ) {
                    516:            FOUND_FREE(hbp, HDR_WORDS);
                    517: #          ifdef GATHERSTATS
                    518:                GC_mem_found += sz;
                    519: #          endif
                    520:            GC_freehblk(hbp);
                    521:        }
                    522:     } else {
                    523:         GC_bool empty = GC_block_empty(hhdr);
                    524:         if (abort_if_found) {
                    525:          GC_reclaim_small_nonempty_block(hbp, (int)abort_if_found);
                    526:         } else if (empty) {
                    527: #        ifdef GATHERSTATS
                    528:             GC_mem_found += BYTES_TO_WORDS(HBLKSIZE);
                    529: #        endif
                    530:           GC_freehblk(hbp);
                    531:         } else {
                    532:           /* group of smaller objects, enqueue the real work */
                    533:           rlh = &(ok -> ok_reclaim_list[sz]);
                    534:           hhdr -> hb_next = *rlh;
                    535:           *rlh = hbp;
                    536:         }
                    537:     }
                    538: }
                    539:
                    540: #if !defined(NO_DEBUGGING)
                    541: /* Routines to gather and print heap block info        */
                    542: /* intended for debugging.  Otherwise should be called */
                    543: /* with lock.                                          */
                    544: static size_t number_of_blocks;
                    545: static size_t total_bytes;
                    546:
                    547: /* Number of set bits in a word.  Not performance critical.    */
                    548: static int set_bits(n)
                    549: word n;
                    550: {
                    551:     register word m = n;
                    552:     register int result = 0;
                    553:
                    554:     while (m > 0) {
                    555:        if (m & 1) result++;
                    556:        m >>= 1;
                    557:     }
                    558:     return(result);
                    559: }
                    560:
                    561: /* Return the number of set mark bits in the given header      */
                    562: int GC_n_set_marks(hhdr)
                    563: hdr * hhdr;
                    564: {
                    565:     register int result = 0;
                    566:     register int i;
                    567:
                    568:     for (i = 0; i < MARK_BITS_SZ; i++) {
                    569:         result += set_bits(hhdr -> hb_marks[i]);
                    570:     }
                    571:     return(result);
                    572: }
                    573:
                    574: /*ARGSUSED*/
                    575: void GC_print_block_descr(h, dummy)
                    576: struct hblk *h;
                    577: word dummy;
                    578: {
                    579:     register hdr * hhdr = HDR(h);
                    580:     register size_t bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
                    581:
                    582:     GC_printf3("(%lu:%lu,%lu)", (unsigned long)(hhdr -> hb_obj_kind),
                    583:                                (unsigned long)bytes,
                    584:                                (unsigned long)(GC_n_set_marks(hhdr)));
                    585:     bytes += HDR_BYTES + HBLKSIZE-1;
                    586:     bytes &= ~(HBLKSIZE-1);
                    587:     total_bytes += bytes;
                    588:     number_of_blocks++;
                    589: }
                    590:
                    591: void GC_print_block_list()
                    592: {
                    593:     GC_printf0("(kind(0=ptrfree,1=normal,2=unc.,3=stubborn):size_in_bytes, #_marks_set)\n");
                    594:     number_of_blocks = 0;
                    595:     total_bytes = 0;
                    596:     GC_apply_to_all_blocks(GC_print_block_descr, (word)0);
                    597:     GC_printf2("\nblocks = %lu, bytes = %lu\n",
                    598:               (unsigned long)number_of_blocks,
                    599:               (unsigned long)total_bytes);
                    600: }
                    601:
                    602: #endif /* NO_DEBUGGING */
                    603:
                    604: /*
                    605:  * Do the same thing on the entire heap, after first clearing small object
                    606:  * free lists (if we are not just looking for leaks).
                    607:  */
                    608: void GC_start_reclaim(abort_if_found)
                    609: int abort_if_found;            /* Abort if a GC_reclaimable object is found */
                    610: {
                    611:     int kind;
                    612:
                    613:     /* Clear reclaim- and free-lists */
                    614:       for (kind = 0; kind < GC_n_kinds; kind++) {
                    615:         register ptr_t *fop;
                    616:         register ptr_t *lim;
                    617:         register struct hblk ** rlp;
                    618:         register struct hblk ** rlim;
                    619:         register struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list;
                    620:
                    621:         if (rlist == 0) continue;      /* This kind not used.  */
                    622:         if (!abort_if_found) {
                    623:             lim = &(GC_obj_kinds[kind].ok_freelist[MAXOBJSZ+1]);
                    624:            for( fop = GC_obj_kinds[kind].ok_freelist; fop < lim; fop++ ) {
                    625:              *fop = 0;
                    626:            }
                    627:        } /* otherwise free list objects are marked,    */
                    628:          /* and its safe to leave them                 */
                    629:        rlim = rlist + MAXOBJSZ+1;
                    630:        for( rlp = rlist; rlp < rlim; rlp++ ) {
                    631:            *rlp = 0;
                    632:        }
                    633:       }
                    634:
                    635: #   ifdef PRINTBLOCKS
                    636:         GC_printf0("GC_reclaim: current block sizes:\n");
                    637:         GC_print_block_list();
                    638: #   endif
                    639:
                    640:   /* Go through all heap blocks (in hblklist) and reclaim unmarked objects */
                    641:   /* or enqueue the block for later processing.                                   */
                    642:     GC_apply_to_all_blocks(GC_reclaim_block, (word)abort_if_found);
                    643:
                    644: }
                    645:
                    646: /*
                    647:  * Sweep blocks of the indicated object size and kind until either the
                    648:  * appropriate free list is nonempty, or there are no more blocks to
                    649:  * sweep.
                    650:  */
                    651: void GC_continue_reclaim(sz, kind)
                    652: word sz;       /* words */
                    653: int kind;
                    654: {
                    655:     register hdr * hhdr;
                    656:     register struct hblk * hbp;
                    657:     register struct obj_kind * ok = &(GC_obj_kinds[kind]);
                    658:     struct hblk ** rlh = ok -> ok_reclaim_list;
                    659:     ptr_t *flh = &(ok -> ok_freelist[sz]);
                    660:
                    661:     if (rlh == 0) return;      /* No blocks of this kind.      */
                    662:     rlh += sz;
                    663:        GC_timerstart();
                    664:     while ((hbp = *rlh) != 0) {
                    665:         hhdr = HDR(hbp);
                    666:         *rlh = hhdr -> hb_next;
                    667:         GC_reclaim_small_nonempty_block(hbp, FALSE);
                    668:         if (*flh != 0) break;
                    669:     }
                    670:        GC_timerstop();
                    671: }
                    672:
                    673: /*
                    674:  * Reclaim all small blocks waiting to be reclaimed.
                    675:  * Abort and return FALSE when/if (*stop_func)() returns TRUE.
                    676:  * If this returns TRUE, then it's safe to restart the world
                    677:  * with incorrectly cleared mark bits.
                    678:  * If ignore_old is TRUE, then reclain only blocks that have been
                    679:  * recently reclaimed, and discard the rest.
                    680:  * Stop_func may be 0.
                    681:  */
                    682: GC_bool GC_reclaim_all(stop_func, ignore_old)
                    683: GC_stop_func stop_func;
                    684: GC_bool ignore_old;
                    685: {
                    686:     register word sz;
                    687:     register int kind;
                    688:     register hdr * hhdr;
                    689:     register struct hblk * hbp;
                    690:     register struct obj_kind * ok;
                    691:     struct hblk ** rlp;
                    692:     struct hblk ** rlh;
                    693: #   ifdef PRINTTIMES
                    694:        CLOCK_TYPE start_time;
                    695:        CLOCK_TYPE done_time;
                    696:
                    697:        GET_TIME(start_time);
                    698: #   endif
                    699:
                    700:        GC_timerstart();
                    701:     for (kind = 0; kind < GC_n_kinds; kind++) {
                    702:        ok = &(GC_obj_kinds[kind]);
                    703:        rlp = ok -> ok_reclaim_list;
                    704:        if (rlp == 0) continue;
                    705:        for (sz = 1; sz <= MAXOBJSZ; sz++) {
                    706:            rlh = rlp + sz;
                    707:            while ((hbp = *rlh) != 0) {
                    708:                if (stop_func != (GC_stop_func)0 && (*stop_func)()) {
                    709:                    return(FALSE);
                    710:                }
                    711:                hhdr = HDR(hbp);
                    712:                *rlh = hhdr -> hb_next;
                    713:                if (!ignore_old || hhdr -> hb_last_reclaimed == GC_gc_no - 1) {
                    714:                    /* It's likely we'll need it this time, too */
                    715:                    /* It's been touched recently, so this      */
                    716:                    /* shouldn't trigger paging.                */
                    717:                    GC_reclaim_small_nonempty_block(hbp, FALSE);
                    718:                }
                    719:             }
                    720:         }
                    721:     }
                    722:        GC_timerstop();
                    723: #   ifdef PRINTTIMES
                    724:        GET_TIME(done_time);
                    725:        GC_printf1("Disposing of reclaim lists took %lu msecs\n",
                    726:                   MS_TIME_DIFF(done_time,start_time));
                    727: #   endif
                    728:     return(TRUE);
                    729: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>