[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.2

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);
1.2     ! noro       83: #   if !defined(MSWIN32) && !defined(MSWINCE)
1.1       noro       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>