[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     ! 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>