Annotation of OpenXM_contrib/gc/checksums.c, Revision 1.1
1.1 ! maekawa 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>