OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [boehm-gc/] [checksums.c] - Blame information for rev 778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 721 jeremybenn
/*
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 "private/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 10000
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 collector.           */
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
    struct hblk *b;
80
 
81
    if (pe -> block != 0 && pe -> block != h + OFFSET) ABORT("goofed");
82
    pe -> old_sum = pe -> new_sum;
83
    pe -> new_sum = GC_checksum(h);
84
#   if !defined(MSWIN32) && !defined(MSWINCE)
85
        if (pe -> new_sum != 0x80000000 && !GC_page_was_ever_dirty(h)) {
86
            GC_printf1("GC_page_was_ever_dirty(0x%lx) is wrong\n",
87
                       (unsigned long)h);
88
        }
89
#   endif
90
    if (GC_page_was_dirty(h)) {
91
        GC_n_dirty++;
92
    } else {
93
        GC_n_clean++;
94
    }
95
    b = h;
96
    while (IS_FORWARDING_ADDR_OR_NIL(hhdr) && hhdr != 0) {
97
        b -= (word)hhdr;
98
        hhdr = HDR(b);
99
    }
100
    if (pe -> new_valid
101
        && hhdr != 0 && hhdr -> hb_descr != 0 /* may contain pointers */
102
        && pe -> old_sum != pe -> new_sum) {
103
        if (!GC_page_was_dirty(h) || !GC_page_was_ever_dirty(h)) {
104
            /* Set breakpoint here */GC_n_dirty_errors++;
105
        }
106
#       ifdef STUBBORN_ALLOC
107
          if ( hhdr -> hb_map != GC_invalid_map
108
            && hhdr -> hb_obj_kind == STUBBORN
109
            && !GC_page_was_changed(h)
110
            && !GC_on_free_list(h)) {
111
            /* if GC_on_free_list(h) then reclaim may have touched it   */
112
            /* without any allocations taking place.                    */
113
            /* Set breakpoint here */GC_n_changed_errors++;
114
          }
115
#       endif
116
    }
117
    pe -> new_valid = TRUE;
118
    pe -> block = h + OFFSET;
119
}
120
 
121
word GC_bytes_in_used_blocks;
122
 
123
void GC_add_block(h, dummy)
124
struct hblk *h;
125
word dummy;
126
{
127
   register hdr * hhdr = HDR(h);
128
   register bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
129
 
130
   bytes += HBLKSIZE-1;
131
   bytes &= ~(HBLKSIZE-1);
132
   GC_bytes_in_used_blocks += bytes;
133
}
134
 
135
void GC_check_blocks()
136
{
137
    word bytes_in_free_blocks = GC_large_free_bytes;
138
 
139
    GC_bytes_in_used_blocks = 0;
140
    GC_apply_to_all_blocks(GC_add_block, (word)0);
141
    GC_printf2("GC_bytes_in_used_blocks = %ld, bytes_in_free_blocks = %ld ",
142
                GC_bytes_in_used_blocks, bytes_in_free_blocks);
143
    GC_printf1("GC_heapsize = %ld\n", GC_heapsize);
144
    if (GC_bytes_in_used_blocks + bytes_in_free_blocks != GC_heapsize) {
145
        GC_printf0("LOST SOME BLOCKS!!\n");
146
    }
147
}
148
 
149
/* Should be called immediately after GC_read_dirty and GC_read_changed. */
150
void GC_check_dirty()
151
{
152
    register int index;
153
    register unsigned i;
154
    register struct hblk *h;
155
    register ptr_t start;
156
 
157
    GC_check_blocks();
158
 
159
    GC_n_dirty_errors = 0;
160
    GC_n_changed_errors = 0;
161
    GC_n_clean = 0;
162
    GC_n_dirty = 0;
163
 
164
    index = 0;
165
    for (i = 0; i < GC_n_heap_sects; i++) {
166
        start = GC_heap_sects[i].hs_start;
167
        for (h = (struct hblk *)start;
168
             h < (struct hblk *)(start + GC_heap_sects[i].hs_bytes);
169
             h++) {
170
             GC_update_check_page(h, index);
171
             index++;
172
             if (index >= NSUMS) goto out;
173
        }
174
    }
175
out:
176
    GC_printf2("Checked %lu clean and %lu dirty pages\n",
177
              (unsigned long) GC_n_clean, (unsigned long) GC_n_dirty);
178
    if (GC_n_dirty_errors > 0) {
179
        GC_printf1("Found %lu dirty bit errors\n",
180
                   (unsigned long)GC_n_dirty_errors);
181
    }
182
    if (GC_n_changed_errors > 0) {
183
        GC_printf1("Found %lu changed bit errors\n",
184
                   (unsigned long)GC_n_changed_errors);
185
        GC_printf0("These may be benign (provoked by nonpointer changes)\n");
186
#       ifdef THREADS
187
            GC_printf0(
188
            "Also expect 1 per thread currently allocating a stubborn obj.\n");
189
#       endif
190
    }
191
}
192
 
193
# else
194
 
195
extern int GC_quiet;
196
        /* ANSI C doesn't allow translation units to be empty.  */
197
        /* So we guarantee this one is nonempty.                */
198
 
199
# endif /* CHECKSUMS */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.