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

Annotation of OpenXM_contrib2/asir2000/gc/ptr_chck.c, Revision 1.1

1.1     ! noro        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>