/*
 * Copyright (c) 1992-1994 by Xerox Corporation.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 */
/* Boehm, March 29, 1995 12:51 pm PST */
# ifdef CHECKSUMS

# include "private/gc_priv.h"

/* This is debugging code intended to verify the results of dirty bit	*/
/* computations. Works only in a single threaded environment.		*/
/* We assume that stubborn objects are changed only when they are 	*/
/* enabled for writing.  (Certain kinds of writing are actually		*/
/* safe under other conditions.)					*/
# define NSUMS 10000

# define OFFSET 0x10000

typedef struct {
	GC_bool new_valid;
	word old_sum;
	word new_sum;
	struct hblk * block;	/* Block to which this refers + OFFSET  */
				/* to hide it from collector.		*/
} page_entry;

page_entry GC_sums [NSUMS];

word GC_checksum(h)
struct hblk *h;
{
    register word *p = (word *)h;
    register word *lim = (word *)(h+1);
    register word result = 0;
    
    while (p < lim) {
        result += *p++;
    }
    return(result | 0x80000000 /* doesn't look like pointer */);
}

# ifdef STUBBORN_ALLOC
/* Check whether a stubborn object from the given block appears on	*/
/* the appropriate free list.						*/
GC_bool GC_on_free_list(h)
struct hblk *h;
{
    register hdr * hhdr = HDR(h);
    register int sz = hhdr -> hb_sz;
    ptr_t p;
    
    if (sz > MAXOBJSZ) return(FALSE);
    for (p = GC_sobjfreelist[sz]; p != 0; p = obj_link(p)) {
        if (HBLKPTR(p) == h) return(TRUE);
    }
    return(FALSE);
}
# endif
 
int GC_n_dirty_errors;
int GC_n_changed_errors;
int GC_n_clean;
int GC_n_dirty;

void GC_update_check_page(h, index)
struct hblk *h;
int index;
{
    page_entry *pe = GC_sums + index;
    register hdr * hhdr = HDR(h);
    struct hblk *b;
    
    if (pe -> block != 0 && pe -> block != h + OFFSET) ABORT("goofed");
    pe -> old_sum = pe -> new_sum;
    pe -> new_sum = GC_checksum(h);
#   if !defined(MSWIN32) && !defined(MSWINCE)
        if (pe -> new_sum != 0x80000000 && !GC_page_was_ever_dirty(h)) {
            GC_printf1("GC_page_was_ever_dirty(0x%lx) is wrong\n",
        	       (unsigned long)h);
        }
#   endif
    if (GC_page_was_dirty(h)) {
    	GC_n_dirty++;
    } else {
    	GC_n_clean++;
    }
    b = h;
    while (IS_FORWARDING_ADDR_OR_NIL(hhdr) && hhdr != 0) {
	b -= (word)hhdr;
	hhdr = HDR(b);
    }
    if (pe -> new_valid
	&& hhdr != 0 && hhdr -> hb_descr != 0 /* may contain pointers */
	&& pe -> old_sum != pe -> new_sum) {
    	if (!GC_page_was_dirty(h) || !GC_page_was_ever_dirty(h)) {
    	    /* Set breakpoint here */GC_n_dirty_errors++;
    	}
#	ifdef STUBBORN_ALLOC
    	  if ( hhdr -> hb_map != GC_invalid_map
    	    && hhdr -> hb_obj_kind == STUBBORN
    	    && !GC_page_was_changed(h)
    	    && !GC_on_free_list(h)) {
    	    /* if GC_on_free_list(h) then reclaim may have touched it	*/
    	    /* without any allocations taking place.			*/
    	    /* Set breakpoint here */GC_n_changed_errors++;
    	  }
#	endif
    }
    pe -> new_valid = TRUE;
    pe -> block = h + OFFSET;
}

word GC_bytes_in_used_blocks;

void GC_add_block(h, dummy)
struct hblk *h;
word dummy;
{
   register hdr * hhdr = HDR(h);
   register bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
   
   bytes += HBLKSIZE-1;
   bytes &= ~(HBLKSIZE-1);
   GC_bytes_in_used_blocks += bytes;
}

void GC_check_blocks()
{
    word bytes_in_free_blocks = GC_large_free_bytes;
    
    GC_bytes_in_used_blocks = 0;
    GC_apply_to_all_blocks(GC_add_block, (word)0);
    GC_printf2("GC_bytes_in_used_blocks = %ld, bytes_in_free_blocks = %ld ",
    		GC_bytes_in_used_blocks, bytes_in_free_blocks);
    GC_printf1("GC_heapsize = %ld\n", GC_heapsize);
    if (GC_bytes_in_used_blocks + bytes_in_free_blocks != GC_heapsize) {
    	GC_printf0("LOST SOME BLOCKS!!\n");
    }
}

/* Should be called immediately after GC_read_dirty and GC_read_changed. */
void GC_check_dirty()
{
    register int index;
    register unsigned i;
    register struct hblk *h;
    register ptr_t start;
    
    GC_check_blocks();
    
    GC_n_dirty_errors = 0;
    GC_n_changed_errors = 0;
    GC_n_clean = 0;
    GC_n_dirty = 0;
    
    index = 0;
    for (i = 0; i < GC_n_heap_sects; i++) {
    	start = GC_heap_sects[i].hs_start;
        for (h = (struct hblk *)start;
             h < (struct hblk *)(start + GC_heap_sects[i].hs_bytes);
             h++) {
             GC_update_check_page(h, index);
             index++;
             if (index >= NSUMS) goto out;
        }
    }
out:
    GC_printf2("Checked %lu clean and %lu dirty pages\n",
    	      (unsigned long) GC_n_clean, (unsigned long) GC_n_dirty);
    if (GC_n_dirty_errors > 0) {
        GC_printf1("Found %lu dirty bit errors\n",
        	   (unsigned long)GC_n_dirty_errors);
    }
    if (GC_n_changed_errors > 0) {
    	GC_printf1("Found %lu changed bit errors\n",
        	   (unsigned long)GC_n_changed_errors);
	GC_printf0("These may be benign (provoked by nonpointer changes)\n");
#	ifdef THREADS
	    GC_printf0(
	    "Also expect 1 per thread currently allocating a stubborn obj.\n");
#	endif
    }
}

# else

extern int GC_quiet;
	/* ANSI C doesn't allow translation units to be empty.	*/
	/* So we guarantee this one is nonempty.		*/

# endif /* CHECKSUMS */
