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

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

1.1       maekawa     1: /*
                      2:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
                      3:  *
                      4:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      5:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      6:  *
                      7:  * Permission is hereby granted to use or copy this program
                      8:  * for any purpose,  provided the above notices are retained on all copies.
                      9:  * Permission to modify the code and to distribute modified code is granted,
                     10:  * provided the above notices are retained, and a notice that the code was
                     11:  * modified is included with the above copyright notice.
                     12:  */
                     13: /* Boehm, September 19, 1995 1:26 pm PDT */
                     14:
                     15: #include "gc_priv.h"
                     16: #include "gc_mark.h"
                     17:
                     18: #ifdef __STDC__
                     19: void GC_default_same_obj_print_proc(GC_PTR p, GC_PTR q)
                     20: #else
                     21: void GC_default_same_obj_print_proc (p, q)
                     22: GC_PTR p, q;
                     23: #endif
                     24: {
                     25:     GC_err_printf2("0x%lx and 0x%lx are not in the same object\n",
                     26:                   (unsigned long)p, (unsigned long)q);
                     27:     ABORT("GC_same_obj test failed");
                     28: }
                     29:
                     30: void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR, GC_PTR))
                     31:                = GC_default_same_obj_print_proc;
                     32:
                     33: /* Check that p and q point to the same object.  Call          */
                     34: /* *GC_same_obj_print_proc if they don't.                      */
                     35: /* Returns the first argument.  (Return value may be hard      */
                     36: /* to use,due to typing issues.  But if we had a suitable      */
                     37: /* preprocessor ...)                                           */
                     38: /* Succeeds if neither p nor q points to the heap.             */
                     39: /* We assume this is performance critical.  (It shouldn't      */
                     40: /* be called by production code, but this can easily make      */
                     41: /* debugging intolerably slow.)                                        */
                     42: #ifdef __STDC__
                     43:   GC_PTR GC_same_obj(register void *p, register void *q)
                     44: #else
                     45:   GC_PTR GC_same_obj(p, q)
                     46:   register char *p, *q;
                     47: #endif
                     48: {
                     49:     register struct hblk *h;
                     50:     register hdr *hhdr;
                     51:     register ptr_t base, limit;
                     52:     register word sz;
                     53:
                     54:     if (!GC_is_initialized) GC_init();
                     55:     hhdr = HDR((word)p);
                     56:     if (hhdr == 0) {
                     57:        if (divHBLKSZ((word)p) != divHBLKSZ((word)q)
                     58:            && HDR((word)q) != 0) {
                     59:            goto fail;
                     60:        }
                     61:        return(p);
                     62:     }
                     63:     /* If it's a pointer to the middle of a large object, move it      */
                     64:     /* to the beginning.                                               */
                     65:     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                     66:        h = HBLKPTR(p) - (word)hhdr;
                     67:        hhdr = HDR(h);
                     68:        while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                     69:           h = FORWARDED_ADDR(h, hhdr);
                     70:           hhdr = HDR(h);
                     71:        }
                     72:        limit = (ptr_t)((word *)h + HDR_WORDS + hhdr -> hb_sz);
                     73:        if ((ptr_t)p >= limit || (ptr_t)q >= limit || (ptr_t)q < (ptr_t)h ) {
                     74:            goto fail;
                     75:        }
                     76:        return(p);
                     77:     }
                     78:     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
                     79:     if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
                     80:       base = (ptr_t)HBLKPTR(p);
                     81:       limit = base + sz;
                     82:       if ((ptr_t)p >= limit) {
                     83:         goto fail;
                     84:       }
                     85:     } else {
                     86: #     ifdef ALL_INTERIOR_POINTERS
                     87:        register map_entry_type map_entry;
                     88:        register int pdispl;
                     89:
                     90:        pdispl = HBLKDISPL(p);
                     91:        map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
                     92:        if (map_entry == OBJ_INVALID) {
                     93:             goto fail;
                     94:         } else {
                     95:             base = (char *)((word)p & ~(WORDS_TO_BYTES(1) - 1));
                     96:             base -= WORDS_TO_BYTES(map_entry);
                     97:        }
                     98: #     else
                     99:        register int offset = HBLKDISPL(p) - HDR_BYTES;
                    100:        register word correction = offset % sz;
                    101:
                    102:        if (HBLKPTR(p) != HBLKPTR(q)) {
                    103:            /* The following computation otherwise fails in this case */
                    104:            goto fail;
                    105:        }
                    106:        base = (ptr_t)p - correction;
                    107: #     endif
                    108:       limit = base + sz;
                    109:     }
                    110:     /* [base, limit) delimits the object containing p, if any. */
                    111:     /* If p is not inside a valid object, then either q is     */
                    112:     /* also outside any valid object, or it is outside                 */
                    113:     /* [base, limit).                                          */
                    114:     if ((ptr_t)q >= limit || (ptr_t)q < base) {
                    115:        goto fail;
                    116:     }
                    117:     return(p);
                    118: fail:
                    119:     (*GC_same_obj_print_proc)((ptr_t)p, (ptr_t)q);
                    120:     return(p);
                    121: }
                    122:
                    123: #ifdef __STDC__
                    124: void GC_default_is_valid_displacement_print_proc (GC_PTR p)
                    125: #else
                    126: void GC_default_is_valid_displacement_print_proc (p)
                    127: GC_PTR p;
                    128: #endif
                    129: {
                    130:     GC_err_printf1("0x%lx does not point to valid object displacement\n",
                    131:                   (unsigned long)p);
                    132:     ABORT("GC_is_valid_displacement test failed");
                    133: }
                    134:
                    135: void (*GC_is_valid_displacement_print_proc) GC_PROTO((GC_PTR)) =
                    136:        GC_default_is_valid_displacement_print_proc;
                    137:
                    138: /* Check that if p is a pointer to a heap page, then it points to      */
                    139: /* a valid displacement within a heap object.                          */
                    140: /* Uninteresting with ALL_INTERIOR_POINTERS.                           */
                    141: /* Always returns its argument.                                                */
                    142: /* Note that we don't lock, since nothing relevant about the header    */
                    143: /* should change while we have a valid object pointer to the block.    */
                    144: #ifdef __STDC__
                    145:   void * GC_is_valid_displacement(void *p)
                    146: #else
                    147:   char *GC_is_valid_displacement(p)
                    148:   char *p;
                    149: #endif
                    150: {
                    151:     register hdr *hhdr;
                    152:     register word pdispl;
                    153:     register struct hblk *h;
                    154:     register map_entry_type map_entry;
                    155:     register word sz;
                    156:
                    157:     if (!GC_is_initialized) GC_init();
                    158:     hhdr = HDR((word)p);
                    159:     if (hhdr == 0) return(p);
                    160:     h = HBLKPTR(p);
                    161: #   ifdef ALL_INTERIOR_POINTERS
                    162:        while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                    163:           h = FORWARDED_ADDR(h, hhdr);
                    164:           hhdr = HDR(h);
                    165:        }
                    166: #   endif
                    167:     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                    168:        goto fail;
                    169:     }
                    170:     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
                    171:     pdispl = HBLKDISPL(p);
                    172:     map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
                    173:     if (map_entry == OBJ_INVALID
                    174:        || sz > MAXOBJSZ && (ptr_t)p >= (ptr_t)h + sz) {
                    175:        goto fail;
                    176:     }
                    177:     return(p);
                    178: fail:
                    179:     (*GC_is_valid_displacement_print_proc)((ptr_t)p);
                    180:     return(p);
                    181: }
                    182:
                    183: #ifdef __STDC__
                    184: void GC_default_is_visible_print_proc(GC_PTR p)
                    185: #else
                    186: void GC_default_is_visible_print_proc(p)
                    187: GC_PTR p;
                    188: #endif
                    189: {
                    190:     GC_err_printf1("0x%lx is not a GC visible pointer location\n",
                    191:                   (unsigned long)p);
                    192:     ABORT("GC_is_visible test failed");
                    193: }
                    194:
                    195: void (*GC_is_visible_print_proc) GC_PROTO((GC_PTR p)) =
                    196:        GC_default_is_visible_print_proc;
                    197:
                    198: /* Could p be a stack address? */
                    199: GC_bool GC_on_stack(p)
                    200: ptr_t p;
                    201: {
                    202: #   ifdef THREADS
                    203:        return(TRUE);
                    204: #   else
                    205:        int dummy;
                    206: #      ifdef STACK_GROWS_DOWN
                    207:            if ((ptr_t)p >= (ptr_t)(&dummy) && (ptr_t)p < GC_stackbottom ) {
                    208:                return(TRUE);
                    209:            }
                    210: #      else
                    211:            if ((ptr_t)p <= (ptr_t)(&dummy) && (ptr_t)p > GC_stackbottom ) {
                    212:                return(TRUE);
                    213:            }
                    214: #      endif
                    215:        return(FALSE);
                    216: #   endif
                    217: }
                    218:
                    219: /* Check that p is visible                                             */
                    220: /* to the collector as a possibly pointer containing location.         */
                    221: /* If it isn't invoke *GC_is_visible_print_proc.                       */
                    222: /* Returns the argument in all cases.  May erroneously succeed         */
                    223: /* in hard cases.  (This is intended for debugging use with            */
                    224: /* untyped allocations.  The idea is that it should be possible, though        */
                    225: /* slow, to add such a call to all indirect pointer stores.)           */
                    226: /* Currently useless for multithreaded worlds.                         */
                    227: #ifdef __STDC__
                    228:   void * GC_is_visible(void *p)
                    229: #else
                    230:   char *GC_is_visible(p)
                    231:   char *p;
                    232: #endif
                    233: {
                    234:     register hdr *hhdr;
                    235:
                    236:     if ((word)p & (ALIGNMENT - 1)) goto fail;
                    237:     if (!GC_is_initialized) GC_init();
                    238: #   ifdef THREADS
                    239:        hhdr = HDR((word)p);
                    240:         if (hhdr != 0 && GC_base(p) == 0) {
                    241:             goto fail;
                    242:         } else {
                    243:             /* May be inside thread stack.  We can't do much. */
                    244:             return(p);
                    245:         }
                    246: #   else
                    247:        /* Check stack first: */
                    248:          if (GC_on_stack(p)) return(p);
                    249:        hhdr = HDR((word)p);
                    250:        if (hhdr == 0) {
                    251:            GC_bool result;
                    252:
                    253:            if (GC_is_static_root(p)) return(p);
                    254:            /* Else do it again correctly:      */
                    255: #           if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \
                    256:                 && !defined(SRC_M3)
                    257:                DISABLE_SIGNALS();
                    258:                GC_register_dynamic_libraries();
                    259:                result = GC_is_static_root(p);
                    260:                ENABLE_SIGNALS();
                    261:                if (result) return(p);
                    262: #          endif
                    263:            goto fail;
                    264:        } else {
                    265:            /* p points to the heap. */
                    266:            word descr;
                    267:            ptr_t base = GC_base(p);    /* Should be manually inlined? */
                    268:
                    269:            if (base == 0) goto fail;
                    270:            if (HBLKPTR(base) != HBLKPTR(p)) hhdr = HDR((word)p);
                    271:            descr = hhdr -> hb_descr;
                    272:     retry:
                    273:            switch(descr & DS_TAGS) {
                    274:                case DS_LENGTH:
                    275:                    if ((word)((ptr_t)p - (ptr_t)base) > (word)descr) goto fail;
                    276:                    break;
                    277:                case DS_BITMAP:
                    278:                    if ((ptr_t)p - (ptr_t)base
                    279:                         >= WORDS_TO_BYTES(BITMAP_BITS)
                    280:                         || ((word)p & (sizeof(word) - 1))) goto fail;
                    281:                    if (!((1 << (WORDSZ - ((ptr_t)p - (ptr_t)base) - 1))
                    282:                          & descr)) goto fail;
                    283:                    break;
                    284:                case DS_PROC:
                    285:                    /* We could try to decipher this partially.         */
                    286:                    /* For now we just punt.                            */
                    287:                    break;
                    288:                case DS_PER_OBJECT:
                    289:                    descr = *(word *)((ptr_t)base + (descr & ~DS_TAGS));
                    290:                    goto retry;
                    291:            }
                    292:            return(p);
                    293:        }
                    294: #   endif
                    295: fail:
                    296:     (*GC_is_visible_print_proc)((ptr_t)p);
                    297:     return(p);
                    298: }
                    299:
                    300:
                    301: GC_PTR GC_pre_incr (p, how_much)
                    302: GC_PTR *p;
                    303: size_t how_much;
                    304: {
                    305:     GC_PTR initial = *p;
                    306:     GC_PTR result = GC_same_obj((GC_PTR)((word)initial + how_much), initial);
                    307:
                    308: #   ifndef ALL_INTERIOR_POINTERS
                    309:        (void) GC_is_valid_displacement(result);
                    310: #   endif
                    311:     return (*p = result);
                    312: }
                    313:
                    314: GC_PTR GC_post_incr (p, how_much)
                    315: GC_PTR *p;
                    316: size_t how_much;
                    317: {
                    318:     GC_PTR initial = *p;
                    319:     GC_PTR result = GC_same_obj((GC_PTR)((word)initial + how_much), initial);
                    320:
                    321: #   ifndef ALL_INTERIOR_POINTERS
                    322:        (void) GC_is_valid_displacement(result);
                    323: #   endif
                    324:     *p = result;
                    325:     return(initial);
                    326: }

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