[BACK]Return to dbg_mlc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gc

Annotation of OpenXM_contrib/gc/dbg_mlc.c, Revision 1.1.1.1

1.1       maekawa     1: /*
                      2:  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
                      3:  * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
                      4:  * Copyright (c) 1997 by Silicon Graphics.  All rights reserved.
                      5:  *
                      6:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      7:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      8:  *
                      9:  * Permission is hereby granted to use or copy this program
                     10:  * for any purpose,  provided the above notices are retained on all copies.
                     11:  * Permission to modify the code and to distribute modified code is granted,
                     12:  * provided the above notices are retained, and a notice that the code was
                     13:  * modified is included with the above copyright notice.
                     14:  */
                     15: /* Boehm, October 9, 1995 1:16 pm PDT */
                     16: # include "gc_priv.h"
                     17:
                     18: void GC_default_print_heap_obj_proc();
                     19: GC_API void GC_register_finalizer_no_order
                     20:        GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
                     21:                  GC_finalization_proc *ofn, GC_PTR *ocd));
                     22:
                     23: /* Do we want to and know how to save the call stack at the time of    */
                     24: /* an allocation?  How much space do we want to use in each object?    */
                     25:
                     26: # define START_FLAG ((word)0xfedcedcb)
                     27: # define END_FLAG ((word)0xbcdecdef)
                     28:        /* Stored both one past the end of user object, and one before  */
                     29:        /* the end of the object as seen by the allocator.              */
                     30:
                     31:
                     32: /* Object header */
                     33: typedef struct {
                     34:     char * oh_string;          /* object descriptor string     */
                     35:     word oh_int;               /* object descriptor integers   */
                     36: #   ifdef NEED_CALLINFO
                     37:       struct callinfo oh_ci[NFRAMES];
                     38: #   endif
                     39:     word oh_sz;                        /* Original malloc arg.         */
                     40:     word oh_sf;                        /* start flag */
                     41: } oh;
                     42: /* The size of the above structure is assumed not to dealign things,   */
                     43: /* and to be a multiple of the word length.                            */
                     44:
                     45: #define DEBUG_BYTES (sizeof (oh) + sizeof (word))
                     46: #undef ROUNDED_UP_WORDS
                     47: #define ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1)
                     48:
                     49:
                     50: #ifdef SAVE_CALL_CHAIN
                     51: #   define ADD_CALL_CHAIN(base, ra) GC_save_callers(((oh *)(base)) -> oh_ci)
                     52: #   define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci)
                     53: #else
                     54: # ifdef GC_ADD_CALLER
                     55: #   define ADD_CALL_CHAIN(base, ra) ((oh *)(base)) -> oh_ci[0].ci_pc = (ra)
                     56: #   define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci)
                     57: # else
                     58: #   define ADD_CALL_CHAIN(base, ra)
                     59: #   define PRINT_CALL_CHAIN(base)
                     60: # endif
                     61: #endif
                     62:
                     63: /* Check whether object with base pointer p has debugging info */
                     64: /* p is assumed to point to a legitimate object in our part    */
                     65: /* of the heap.                                                        */
                     66: GC_bool GC_has_debug_info(p)
                     67: ptr_t p;
                     68: {
                     69:     register oh * ohdr = (oh *)p;
                     70:     register ptr_t body = (ptr_t)(ohdr + 1);
                     71:     register word sz = GC_size((ptr_t) ohdr);
                     72:
                     73:     if (HBLKPTR((ptr_t)ohdr) != HBLKPTR((ptr_t)body)
                     74:         || sz < sizeof (oh)) {
                     75:         return(FALSE);
                     76:     }
                     77:     if (ohdr -> oh_sz == sz) {
                     78:        /* Object may have had debug info, but has been deallocated     */
                     79:        return(FALSE);
                     80:     }
                     81:     if (ohdr -> oh_sf == (START_FLAG ^ (word)body)) return(TRUE);
                     82:     if (((word *)ohdr)[BYTES_TO_WORDS(sz)-1] == (END_FLAG ^ (word)body)) {
                     83:         return(TRUE);
                     84:     }
                     85:     return(FALSE);
                     86: }
                     87:
                     88: /* Store debugging info into p.  Return displaced pointer. */
                     89: /* Assumes we don't hold allocation lock.                 */
                     90: ptr_t GC_store_debug_info(p, sz, string, integer)
                     91: register ptr_t p;      /* base pointer */
                     92: word sz;       /* bytes */
                     93: char * string;
                     94: word integer;
                     95: {
                     96:     register word * result = (word *)((oh *)p + 1);
                     97:     DCL_LOCK_STATE;
                     98:
                     99:     /* There is some argument that we should dissble signals here.     */
                    100:     /* But that's expensive.  And this way things should only appear   */
                    101:     /* inconsistent while we're in the handler.                                */
                    102:     LOCK();
                    103:     ((oh *)p) -> oh_string = string;
                    104:     ((oh *)p) -> oh_int = integer;
                    105:     ((oh *)p) -> oh_sz = sz;
                    106:     ((oh *)p) -> oh_sf = START_FLAG ^ (word)result;
                    107:     ((word *)p)[BYTES_TO_WORDS(GC_size(p))-1] =
                    108:          result[ROUNDED_UP_WORDS(sz)] = END_FLAG ^ (word)result;
                    109:     UNLOCK();
                    110:     return((ptr_t)result);
                    111: }
                    112:
                    113: /* Check the object with debugging info at p           */
                    114: /* return NIL if it's OK.  Else return clobbered       */
                    115: /* address.                                            */
                    116: ptr_t GC_check_annotated_obj(ohdr)
                    117: register oh * ohdr;
                    118: {
                    119:     register ptr_t body = (ptr_t)(ohdr + 1);
                    120:     register word gc_sz = GC_size((ptr_t)ohdr);
                    121:     if (ohdr -> oh_sz + DEBUG_BYTES > gc_sz) {
                    122:         return((ptr_t)(&(ohdr -> oh_sz)));
                    123:     }
                    124:     if (ohdr -> oh_sf != (START_FLAG ^ (word)body)) {
                    125:         return((ptr_t)(&(ohdr -> oh_sf)));
                    126:     }
                    127:     if (((word *)ohdr)[BYTES_TO_WORDS(gc_sz)-1] != (END_FLAG ^ (word)body)) {
                    128:         return((ptr_t)((word *)ohdr + BYTES_TO_WORDS(gc_sz)-1));
                    129:     }
                    130:     if (((word *)body)[ROUNDED_UP_WORDS(ohdr -> oh_sz)]
                    131:         != (END_FLAG ^ (word)body)) {
                    132:         return((ptr_t)((word *)body + ROUNDED_UP_WORDS(ohdr -> oh_sz)));
                    133:     }
                    134:     return(0);
                    135: }
                    136:
                    137: void GC_print_obj(p)
                    138: ptr_t p;
                    139: {
                    140:     register oh * ohdr = (oh *)GC_base(p);
                    141:
                    142:     GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));
                    143:     GC_err_puts(ohdr -> oh_string);
                    144:     GC_err_printf2(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int),
                    145:                                      (unsigned long)(ohdr -> oh_sz));
                    146:     PRINT_CALL_CHAIN(ohdr);
                    147: }
                    148:
                    149: void GC_debug_print_heap_obj_proc(p)
                    150: ptr_t p;
                    151: {
                    152:     if (GC_has_debug_info(p)) {
                    153:        GC_print_obj(p);
                    154:     } else {
                    155:        GC_default_print_heap_obj_proc(p);
                    156:     }
                    157: }
                    158:
                    159: void GC_print_smashed_obj(p, clobbered_addr)
                    160: ptr_t p, clobbered_addr;
                    161: {
                    162:     register oh * ohdr = (oh *)GC_base(p);
                    163:
                    164:     GC_err_printf2("0x%lx in object at 0x%lx(", (unsigned long)clobbered_addr,
                    165:                                                (unsigned long)p);
                    166:     if (clobbered_addr <= (ptr_t)(&(ohdr -> oh_sz))
                    167:         || ohdr -> oh_string == 0) {
                    168:         GC_err_printf1("<smashed>, appr. sz = %ld)\n",
                    169:                       (GC_size((ptr_t)ohdr) - DEBUG_BYTES));
                    170:     } else {
                    171:         if (ohdr -> oh_string[0] == '\0') {
                    172:             GC_err_puts("EMPTY(smashed?)");
                    173:         } else {
                    174:             GC_err_puts(ohdr -> oh_string);
                    175:         }
                    176:         GC_err_printf2(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int),
                    177:                                          (unsigned long)(ohdr -> oh_sz));
                    178:         PRINT_CALL_CHAIN(ohdr);
                    179:     }
                    180: }
                    181:
                    182: void GC_check_heap_proc();
                    183:
                    184: void GC_start_debugging()
                    185: {
                    186:     GC_check_heap = GC_check_heap_proc;
                    187:     GC_print_heap_obj = GC_debug_print_heap_obj_proc;
                    188:     GC_debugging_started = TRUE;
                    189:     GC_register_displacement((word)sizeof(oh));
                    190: }
                    191:
                    192: # if defined(__STDC__) || defined(__cplusplus)
                    193:     void GC_debug_register_displacement(GC_word offset)
                    194: # else
                    195:     void GC_debug_register_displacement(offset)
                    196:     GC_word offset;
                    197: # endif
                    198: {
                    199:     GC_register_displacement(offset);
                    200:     GC_register_displacement((word)sizeof(oh) + offset);
                    201: }
                    202:
                    203: # ifdef GC_ADD_CALLER
                    204: #   define EXTRA_ARGS word ra, char * s, int i
                    205: #   define OPT_RA ra,
                    206: # else
                    207: #   define EXTRA_ARGS char * s, int i
                    208: #   define OPT_RA
                    209: # endif
                    210:
                    211: # ifdef __STDC__
                    212:     GC_PTR GC_debug_malloc(size_t lb, EXTRA_ARGS)
                    213: # else
                    214:     GC_PTR GC_debug_malloc(lb, s, i)
                    215:     size_t lb;
                    216:     char * s;
                    217:     int i;
                    218: #   ifdef GC_ADD_CALLER
                    219:        --> GC_ADD_CALLER not implemented for K&R C
                    220: #   endif
                    221: # endif
                    222: {
                    223:     GC_PTR result = GC_malloc(lb + DEBUG_BYTES);
                    224:
                    225:     if (result == 0) {
                    226:         GC_err_printf1("GC_debug_malloc(%ld) returning NIL (",
                    227:                       (unsigned long) lb);
                    228:         GC_err_puts(s);
                    229:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    230:         return(0);
                    231:     }
                    232:     if (!GC_debugging_started) {
                    233:        GC_start_debugging();
                    234:     }
                    235:     ADD_CALL_CHAIN(result, ra);
                    236:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    237: }
                    238:
                    239: #ifdef STUBBORN_ALLOC
                    240: # ifdef __STDC__
                    241:     GC_PTR GC_debug_malloc_stubborn(size_t lb, EXTRA_ARGS)
                    242: # else
                    243:     GC_PTR GC_debug_malloc_stubborn(lb, s, i)
                    244:     size_t lb;
                    245:     char * s;
                    246:     int i;
                    247: # endif
                    248: {
                    249:     GC_PTR result = GC_malloc_stubborn(lb + DEBUG_BYTES);
                    250:
                    251:     if (result == 0) {
                    252:         GC_err_printf1("GC_debug_malloc(%ld) returning NIL (",
                    253:                       (unsigned long) lb);
                    254:         GC_err_puts(s);
                    255:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    256:         return(0);
                    257:     }
                    258:     if (!GC_debugging_started) {
                    259:        GC_start_debugging();
                    260:     }
                    261:     ADD_CALL_CHAIN(result, ra);
                    262:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    263: }
                    264:
                    265: void GC_debug_change_stubborn(p)
                    266: GC_PTR p;
                    267: {
                    268:     register GC_PTR q = GC_base(p);
                    269:     register hdr * hhdr;
                    270:
                    271:     if (q == 0) {
                    272:         GC_err_printf1("Bad argument: 0x%lx to GC_debug_change_stubborn\n",
                    273:                       (unsigned long) p);
                    274:         ABORT("GC_debug_change_stubborn: bad arg");
                    275:     }
                    276:     hhdr = HDR(q);
                    277:     if (hhdr -> hb_obj_kind != STUBBORN) {
                    278:         GC_err_printf1("GC_debug_change_stubborn arg not stubborn: 0x%lx\n",
                    279:                       (unsigned long) p);
                    280:         ABORT("GC_debug_change_stubborn: arg not stubborn");
                    281:     }
                    282:     GC_change_stubborn(q);
                    283: }
                    284:
                    285: void GC_debug_end_stubborn_change(p)
                    286: GC_PTR p;
                    287: {
                    288:     register GC_PTR q = GC_base(p);
                    289:     register hdr * hhdr;
                    290:
                    291:     if (q == 0) {
                    292:         GC_err_printf1("Bad argument: 0x%lx to GC_debug_end_stubborn_change\n",
                    293:                       (unsigned long) p);
                    294:         ABORT("GC_debug_end_stubborn_change: bad arg");
                    295:     }
                    296:     hhdr = HDR(q);
                    297:     if (hhdr -> hb_obj_kind != STUBBORN) {
                    298:         GC_err_printf1("debug_end_stubborn_change arg not stubborn: 0x%lx\n",
                    299:                       (unsigned long) p);
                    300:         ABORT("GC_debug_end_stubborn_change: arg not stubborn");
                    301:     }
                    302:     GC_end_stubborn_change(q);
                    303: }
                    304:
                    305: #endif /* STUBBORN_ALLOC */
                    306:
                    307: # ifdef __STDC__
                    308:     GC_PTR GC_debug_malloc_atomic(size_t lb, EXTRA_ARGS)
                    309: # else
                    310:     GC_PTR GC_debug_malloc_atomic(lb, s, i)
                    311:     size_t lb;
                    312:     char * s;
                    313:     int i;
                    314: # endif
                    315: {
                    316:     GC_PTR result = GC_malloc_atomic(lb + DEBUG_BYTES);
                    317:
                    318:     if (result == 0) {
                    319:         GC_err_printf1("GC_debug_malloc_atomic(%ld) returning NIL (",
                    320:                      (unsigned long) lb);
                    321:         GC_err_puts(s);
                    322:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    323:         return(0);
                    324:     }
                    325:     if (!GC_debugging_started) {
                    326:         GC_start_debugging();
                    327:     }
                    328:     ADD_CALL_CHAIN(result, ra);
                    329:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    330: }
                    331:
                    332: # ifdef __STDC__
                    333:     GC_PTR GC_debug_malloc_uncollectable(size_t lb, EXTRA_ARGS)
                    334: # else
                    335:     GC_PTR GC_debug_malloc_uncollectable(lb, s, i)
                    336:     size_t lb;
                    337:     char * s;
                    338:     int i;
                    339: # endif
                    340: {
                    341:     GC_PTR result = GC_malloc_uncollectable(lb + DEBUG_BYTES);
                    342:
                    343:     if (result == 0) {
                    344:         GC_err_printf1("GC_debug_malloc_uncollectable(%ld) returning NIL (",
                    345:                      (unsigned long) lb);
                    346:         GC_err_puts(s);
                    347:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    348:         return(0);
                    349:     }
                    350:     if (!GC_debugging_started) {
                    351:         GC_start_debugging();
                    352:     }
                    353:     ADD_CALL_CHAIN(result, ra);
                    354:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    355: }
                    356:
                    357: #ifdef ATOMIC_UNCOLLECTABLE
                    358: # ifdef __STDC__
                    359:     GC_PTR GC_debug_malloc_atomic_uncollectable(size_t lb, EXTRA_ARGS)
                    360: # else
                    361:     GC_PTR GC_debug_malloc_atomic_uncollectable(lb, s, i)
                    362:     size_t lb;
                    363:     char * s;
                    364:     int i;
                    365: # endif
                    366: {
                    367:     GC_PTR result = GC_malloc_atomic_uncollectable(lb + DEBUG_BYTES);
                    368:
                    369:     if (result == 0) {
                    370:         GC_err_printf1(
                    371:                "GC_debug_malloc_atomic_uncollectable(%ld) returning NIL (",
                    372:                 (unsigned long) lb);
                    373:         GC_err_puts(s);
                    374:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    375:         return(0);
                    376:     }
                    377:     if (!GC_debugging_started) {
                    378:         GC_start_debugging();
                    379:     }
                    380:     ADD_CALL_CHAIN(result, ra);
                    381:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    382: }
                    383: #endif /* ATOMIC_UNCOLLECTABLE */
                    384:
                    385: # ifdef __STDC__
                    386:     void GC_debug_free(GC_PTR p)
                    387: # else
                    388:     void GC_debug_free(p)
                    389:     GC_PTR p;
                    390: # endif
                    391: {
                    392:     register GC_PTR base = GC_base(p);
                    393:     register ptr_t clobbered;
                    394:
                    395:     if (base == 0) {
                    396:         GC_err_printf1("Attempt to free invalid pointer %lx\n",
                    397:                       (unsigned long)p);
                    398:         if (p != 0) ABORT("free(invalid pointer)");
                    399:     }
                    400:     if ((ptr_t)p - (ptr_t)base != sizeof(oh)) {
                    401:         GC_err_printf1(
                    402:                  "GC_debug_free called on pointer %lx wo debugging info\n",
                    403:                  (unsigned long)p);
                    404:     } else {
                    405:       clobbered = GC_check_annotated_obj((oh *)base);
                    406:       if (clobbered != 0) {
                    407:         if (((oh *)base) -> oh_sz == GC_size(base)) {
                    408:             GC_err_printf0(
                    409:                   "GC_debug_free: found previously deallocated (?) object at ");
                    410:         } else {
                    411:             GC_err_printf0("GC_debug_free: found smashed object at ");
                    412:         }
                    413:         GC_print_smashed_obj(p, clobbered);
                    414:       }
                    415:       /* Invalidate size */
                    416:       ((oh *)base) -> oh_sz = GC_size(base);
                    417:     }
                    418: #   ifdef FIND_LEAK
                    419:         GC_free(base);
                    420: #   else
                    421:        {
                    422:            register hdr * hhdr = HDR(p);
                    423:            GC_bool uncollectable = FALSE;
                    424:
                    425:            if (hhdr ->  hb_obj_kind == UNCOLLECTABLE) {
                    426:                uncollectable = TRUE;
                    427:            }
                    428: #          ifdef ATOMIC_UNCOLLECTABLE
                    429:                if (hhdr ->  hb_obj_kind == AUNCOLLECTABLE) {
                    430:                    uncollectable = TRUE;
                    431:                }
                    432: #          endif
                    433:            if (uncollectable) GC_free(base);
                    434:        }
                    435: #   endif
                    436: }
                    437:
                    438: # ifdef __STDC__
                    439:     GC_PTR GC_debug_realloc(GC_PTR p, size_t lb, EXTRA_ARGS)
                    440: # else
                    441:     GC_PTR GC_debug_realloc(p, lb, s, i)
                    442:     GC_PTR p;
                    443:     size_t lb;
                    444:     char *s;
                    445:     int i;
                    446: # endif
                    447: {
                    448:     register GC_PTR base = GC_base(p);
                    449:     register ptr_t clobbered;
                    450:     register GC_PTR result;
                    451:     register size_t copy_sz = lb;
                    452:     register size_t old_sz;
                    453:     register hdr * hhdr;
                    454:
                    455:     if (p == 0) return(GC_debug_malloc(lb, OPT_RA s, i));
                    456:     if (base == 0) {
                    457:         GC_err_printf1(
                    458:               "Attempt to reallocate invalid pointer %lx\n", (unsigned long)p);
                    459:         ABORT("realloc(invalid pointer)");
                    460:     }
                    461:     if ((ptr_t)p - (ptr_t)base != sizeof(oh)) {
                    462:         GC_err_printf1(
                    463:                "GC_debug_realloc called on pointer %lx wo debugging info\n",
                    464:                (unsigned long)p);
                    465:         return(GC_realloc(p, lb));
                    466:     }
                    467:     hhdr = HDR(base);
                    468:     switch (hhdr -> hb_obj_kind) {
                    469: #    ifdef STUBBORN_ALLOC
                    470:       case STUBBORN:
                    471:         result = GC_debug_malloc_stubborn(lb, OPT_RA s, i);
                    472:         break;
                    473: #    endif
                    474:       case NORMAL:
                    475:         result = GC_debug_malloc(lb, OPT_RA s, i);
                    476:         break;
                    477:       case PTRFREE:
                    478:         result = GC_debug_malloc_atomic(lb, OPT_RA s, i);
                    479:         break;
                    480:       case UNCOLLECTABLE:
                    481:        result = GC_debug_malloc_uncollectable(lb, OPT_RA s, i);
                    482:        break;
                    483: #    ifdef ATOMIC_UNCOLLECTABLE
                    484:       case AUNCOLLECTABLE:
                    485:        result = GC_debug_malloc_atomic_uncollectable(lb, OPT_RA s, i);
                    486:        break;
                    487: #    endif
                    488:       default:
                    489:         GC_err_printf0("GC_debug_realloc: encountered bad kind\n");
                    490:         ABORT("bad kind");
                    491:     }
                    492:     clobbered = GC_check_annotated_obj((oh *)base);
                    493:     if (clobbered != 0) {
                    494:         GC_err_printf0("GC_debug_realloc: found smashed object at ");
                    495:         GC_print_smashed_obj(p, clobbered);
                    496:     }
                    497:     old_sz = ((oh *)base) -> oh_sz;
                    498:     if (old_sz < copy_sz) copy_sz = old_sz;
                    499:     if (result == 0) return(0);
                    500:     BCOPY(p, result,  copy_sz);
                    501:     GC_debug_free(p);
                    502:     return(result);
                    503: }
                    504:
                    505: /* Check all marked objects in the given block for validity */
                    506: /*ARGSUSED*/
                    507: void GC_check_heap_block(hbp, dummy)
                    508: register struct hblk *hbp;     /* ptr to current heap block            */
                    509: word dummy;
                    510: {
                    511:     register struct hblkhdr * hhdr = HDR(hbp);
                    512:     register word sz = hhdr -> hb_sz;
                    513:     register int word_no;
                    514:     register word *p, *plim;
                    515:
                    516:     p = (word *)(hbp->hb_body);
                    517:     word_no = HDR_WORDS;
                    518:     if (sz > MAXOBJSZ) {
                    519:        plim = p;
                    520:     } else {
                    521:        plim = (word *)((((word)hbp) + HBLKSIZE) - WORDS_TO_BYTES(sz));
                    522:     }
                    523:     /* go through all words in block */
                    524:        while( p <= plim ) {
                    525:            if( mark_bit_from_hdr(hhdr, word_no)
                    526:                && GC_has_debug_info((ptr_t)p)) {
                    527:                ptr_t clobbered = GC_check_annotated_obj((oh *)p);
                    528:
                    529:                if (clobbered != 0) {
                    530:                    GC_err_printf0(
                    531:                        "GC_check_heap_block: found smashed object at ");
                    532:                    GC_print_smashed_obj((ptr_t)p, clobbered);
                    533:                }
                    534:            }
                    535:            word_no += sz;
                    536:            p += sz;
                    537:        }
                    538: }
                    539:
                    540:
                    541: /* This assumes that all accessible objects are marked, and that       */
                    542: /* I hold the allocation lock. Normally called by collector.           */
                    543: void GC_check_heap_proc()
                    544: {
                    545: #   ifndef SMALL_CONFIG
                    546:        if (sizeof(oh) & (2 * sizeof(word) - 1) != 0) {
                    547:            ABORT("Alignment problem: object header has inappropriate size\n");
                    548:        }
                    549: #   endif
                    550:     GC_apply_to_all_blocks(GC_check_heap_block, (word)0);
                    551: }
                    552:
                    553: struct closure {
                    554:     GC_finalization_proc cl_fn;
                    555:     GC_PTR cl_data;
                    556: };
                    557:
                    558: # ifdef __STDC__
                    559:     void * GC_make_closure(GC_finalization_proc fn, void * data)
                    560: # else
                    561:     GC_PTR GC_make_closure(fn, data)
                    562:     GC_finalization_proc fn;
                    563:     GC_PTR data;
                    564: # endif
                    565: {
                    566:     struct closure * result =
                    567:                (struct closure *) GC_malloc(sizeof (struct closure));
                    568:
                    569:     result -> cl_fn = fn;
                    570:     result -> cl_data = data;
                    571:     return((GC_PTR)result);
                    572: }
                    573:
                    574: # ifdef __STDC__
                    575:     void GC_debug_invoke_finalizer(void * obj, void * data)
                    576: # else
                    577:     void GC_debug_invoke_finalizer(obj, data)
                    578:     char * obj;
                    579:     char * data;
                    580: # endif
                    581: {
                    582:     register struct closure * cl = (struct closure *) data;
                    583:
                    584:     (*(cl -> cl_fn))((GC_PTR)((char *)obj + sizeof(oh)), cl -> cl_data);
                    585: }
                    586:
                    587:
                    588: # ifdef __STDC__
                    589:     void GC_debug_register_finalizer(GC_PTR obj, GC_finalization_proc fn,
                    590:                                     GC_PTR cd, GC_finalization_proc *ofn,
                    591:                                     GC_PTR *ocd)
                    592: # else
                    593:     void GC_debug_register_finalizer(obj, fn, cd, ofn, ocd)
                    594:     GC_PTR obj;
                    595:     GC_finalization_proc fn;
                    596:     GC_PTR cd;
                    597:     GC_finalization_proc *ofn;
                    598:     GC_PTR *ocd;
                    599: # endif
                    600: {
                    601:     ptr_t base = GC_base(obj);
                    602:     if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
                    603:         GC_err_printf1(
                    604:            "GC_register_finalizer called with non-base-pointer 0x%lx\n",
                    605:            obj);
                    606:     }
                    607:     GC_register_finalizer(base, GC_debug_invoke_finalizer,
                    608:                          GC_make_closure(fn,cd), ofn, ocd);
                    609: }
                    610:
                    611: # ifdef __STDC__
                    612:     void GC_debug_register_finalizer_no_order
                    613:                                    (GC_PTR obj, GC_finalization_proc fn,
                    614:                                     GC_PTR cd, GC_finalization_proc *ofn,
                    615:                                     GC_PTR *ocd)
                    616: # else
                    617:     void GC_debug_register_finalizer_no_order
                    618:                                    (obj, fn, cd, ofn, ocd)
                    619:     GC_PTR obj;
                    620:     GC_finalization_proc fn;
                    621:     GC_PTR cd;
                    622:     GC_finalization_proc *ofn;
                    623:     GC_PTR *ocd;
                    624: # endif
                    625: {
                    626:     ptr_t base = GC_base(obj);
                    627:     if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
                    628:         GC_err_printf1(
                    629:          "GC_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
                    630:          obj);
                    631:     }
                    632:     GC_register_finalizer_no_order(base, GC_debug_invoke_finalizer,
                    633:                                      GC_make_closure(fn,cd), ofn, ocd);
                    634:  }
                    635:
                    636: # ifdef __STDC__
                    637:     void GC_debug_register_finalizer_ignore_self
                    638:                                    (GC_PTR obj, GC_finalization_proc fn,
                    639:                                     GC_PTR cd, GC_finalization_proc *ofn,
                    640:                                     GC_PTR *ocd)
                    641: # else
                    642:     void GC_debug_register_finalizer_ignore_self
                    643:                                    (obj, fn, cd, ofn, ocd)
                    644:     GC_PTR obj;
                    645:     GC_finalization_proc fn;
                    646:     GC_PTR cd;
                    647:     GC_finalization_proc *ofn;
                    648:     GC_PTR *ocd;
                    649: # endif
                    650: {
                    651:     ptr_t base = GC_base(obj);
                    652:     if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
                    653:         GC_err_printf1(
                    654:            "GC_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
                    655:            obj);
                    656:     }
                    657:     GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer,
                    658:                                      GC_make_closure(fn,cd), ofn, ocd);
                    659: }

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