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

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

1.1     ! noro        1: /*
        !             2:  * Copyright (c) 1992-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, March 29, 1995 12:51 pm PST */
        !            14: # ifdef CHECKSUMS
        !            15:
        !            16: # include "gc_priv.h"
        !            17:
        !            18: /* This is debugging code intended to verify the results of dirty bit  */
        !            19: /* computations. Works only in a single threaded environment.          */
        !            20: /* We assume that stubborn objects are changed only when they are      */
        !            21: /* enabled for writing.  (Certain kinds of writing are actually                */
        !            22: /* safe under other conditions.)                                       */
        !            23: # define NSUMS 2000
        !            24:
        !            25: # define OFFSET 0x10000
        !            26:
        !            27: typedef struct {
        !            28:        GC_bool new_valid;
        !            29:        word old_sum;
        !            30:        word new_sum;
        !            31:        struct hblk * block;    /* Block to which this refers + OFFSET  */
        !            32:                                /* to hide it from colector.            */
        !            33: } page_entry;
        !            34:
        !            35: page_entry GC_sums [NSUMS];
        !            36:
        !            37: word GC_checksum(h)
        !            38: struct hblk *h;
        !            39: {
        !            40:     register word *p = (word *)h;
        !            41:     register word *lim = (word *)(h+1);
        !            42:     register word result = 0;
        !            43:
        !            44:     while (p < lim) {
        !            45:         result += *p++;
        !            46:     }
        !            47:     return(result | 0x80000000 /* doesn't look like pointer */);
        !            48: }
        !            49:
        !            50: # ifdef STUBBORN_ALLOC
        !            51: /* Check whether a stubborn object from the given block appears on     */
        !            52: /* the appropriate free list.                                          */
        !            53: GC_bool GC_on_free_list(h)
        !            54: struct hblk *h;
        !            55: {
        !            56:     register hdr * hhdr = HDR(h);
        !            57:     register int sz = hhdr -> hb_sz;
        !            58:     ptr_t p;
        !            59:
        !            60:     if (sz > MAXOBJSZ) return(FALSE);
        !            61:     for (p = GC_sobjfreelist[sz]; p != 0; p = obj_link(p)) {
        !            62:         if (HBLKPTR(p) == h) return(TRUE);
        !            63:     }
        !            64:     return(FALSE);
        !            65: }
        !            66: # endif
        !            67:
        !            68: int GC_n_dirty_errors;
        !            69: int GC_n_changed_errors;
        !            70: int GC_n_clean;
        !            71: int GC_n_dirty;
        !            72:
        !            73: void GC_update_check_page(h, index)
        !            74: struct hblk *h;
        !            75: int index;
        !            76: {
        !            77:     page_entry *pe = GC_sums + index;
        !            78:     register hdr * hhdr = HDR(h);
        !            79:
        !            80:     if (pe -> block != 0 && pe -> block != h + OFFSET) ABORT("goofed");
        !            81:     pe -> old_sum = pe -> new_sum;
        !            82:     pe -> new_sum = GC_checksum(h);
        !            83: #   ifndef MSWIN32
        !            84:         if (pe -> new_sum != 0 && !GC_page_was_ever_dirty(h)) {
        !            85:             GC_printf1("GC_page_was_ever_dirty(0x%lx) is wrong\n",
        !            86:                       (unsigned long)h);
        !            87:         }
        !            88: #   endif
        !            89:     if (GC_page_was_dirty(h)) {
        !            90:        GC_n_dirty++;
        !            91:     } else {
        !            92:        GC_n_clean++;
        !            93:     }
        !            94:     if (pe -> new_valid && pe -> old_sum != pe -> new_sum) {
        !            95:        if (!GC_page_was_dirty(h) || !GC_page_was_ever_dirty(h)) {
        !            96:            /* Set breakpoint here */GC_n_dirty_errors++;
        !            97:        }
        !            98: #      ifdef STUBBORN_ALLOC
        !            99:          if (!IS_FORWARDING_ADDR_OR_NIL(hhdr)
        !           100:            && hhdr -> hb_map != GC_invalid_map
        !           101:            && hhdr -> hb_obj_kind == STUBBORN
        !           102:            && !GC_page_was_changed(h)
        !           103:            && !GC_on_free_list(h)) {
        !           104:            /* if GC_on_free_list(h) then reclaim may have touched it   */
        !           105:            /* without any allocations taking place.                    */
        !           106:            /* Set breakpoint here */GC_n_changed_errors++;
        !           107:          }
        !           108: #      endif
        !           109:     }
        !           110:     pe -> new_valid = TRUE;
        !           111:     pe -> block = h + OFFSET;
        !           112: }
        !           113:
        !           114: word GC_bytes_in_used_blocks;
        !           115:
        !           116: void GC_add_block(h, dummy)
        !           117: struct hblk *h;
        !           118: word dummy;
        !           119: {
        !           120:    register hdr * hhdr = HDR(h);
        !           121:    register bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
        !           122:
        !           123:    bytes += HDR_BYTES + HBLKSIZE-1;
        !           124:    bytes &= ~(HBLKSIZE-1);
        !           125:    GC_bytes_in_used_blocks += bytes;
        !           126: }
        !           127:
        !           128: void GC_check_blocks()
        !           129: {
        !           130:     word bytes_in_free_blocks = 0;
        !           131:     struct hblk * h = GC_hblkfreelist;
        !           132:     hdr * hhdr = HDR(h);
        !           133:     word sz;
        !           134:
        !           135:     GC_bytes_in_used_blocks = 0;
        !           136:     GC_apply_to_all_blocks(GC_add_block, (word)0);
        !           137:     while (h != 0) {
        !           138:         sz = hhdr -> hb_sz;
        !           139:         bytes_in_free_blocks += sz;
        !           140:         h = hhdr -> hb_next;
        !           141:         hhdr = HDR(h);
        !           142:     }
        !           143:     GC_printf2("GC_bytes_in_used_blocks = %ld, bytes_in_free_blocks = %ld ",
        !           144:                GC_bytes_in_used_blocks, bytes_in_free_blocks);
        !           145:     GC_printf1("GC_heapsize = %ld\n", GC_heapsize);
        !           146:     if (GC_bytes_in_used_blocks + bytes_in_free_blocks != GC_heapsize) {
        !           147:        GC_printf0("LOST SOME BLOCKS!!\n");
        !           148:     }
        !           149: }
        !           150:
        !           151: /* Should be called immediately after GC_read_dirty and GC_read_changed. */
        !           152: void GC_check_dirty()
        !           153: {
        !           154:     register int index;
        !           155:     register unsigned i;
        !           156:     register struct hblk *h;
        !           157:     register ptr_t start;
        !           158:
        !           159:     GC_check_blocks();
        !           160:
        !           161:     GC_n_dirty_errors = 0;
        !           162:     GC_n_changed_errors = 0;
        !           163:     GC_n_clean = 0;
        !           164:     GC_n_dirty = 0;
        !           165:
        !           166:     index = 0;
        !           167:     for (i = 0; i < GC_n_heap_sects; i++) {
        !           168:        start = GC_heap_sects[i].hs_start;
        !           169:         for (h = (struct hblk *)start;
        !           170:              h < (struct hblk *)(start + GC_heap_sects[i].hs_bytes);
        !           171:              h++) {
        !           172:              GC_update_check_page(h, index);
        !           173:              index++;
        !           174:              if (index >= NSUMS) goto out;
        !           175:         }
        !           176:     }
        !           177: out:
        !           178:     GC_printf2("Checked %lu clean and %lu dirty pages\n",
        !           179:              (unsigned long) GC_n_clean, (unsigned long) GC_n_dirty);
        !           180:     if (GC_n_dirty_errors > 0) {
        !           181:         GC_printf1("Found %lu dirty bit errors\n",
        !           182:                   (unsigned long)GC_n_dirty_errors);
        !           183:     }
        !           184:     if (GC_n_changed_errors > 0) {
        !           185:        GC_printf1("Found %lu changed bit errors\n",
        !           186:                   (unsigned long)GC_n_changed_errors);
        !           187:        GC_printf0("These may be benign (provoked by nonpointer changes)\n");
        !           188: #      ifdef THREADS
        !           189:            GC_printf0(
        !           190:            "Also expect 1 per thread currently allocating a stubborn obj.\n");
        !           191: #      endif
        !           192:     }
        !           193: }
        !           194:
        !           195: # else
        !           196:
        !           197: extern int GC_quiet;
        !           198:        /* ANSI C doesn't allow translation units to be empty.  */
        !           199:        /* So we guarantee this one is nonempty.                */
        !           200:
        !           201: # endif /* CHECKSUMS */

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