Annotation of OpenXM_contrib2/asir2000/gc5.3/ptr_chck.c, Revision 1.1.1.1
1.1 noro 1: /*
2: * Copyright (c) 1991-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, September 19, 1995 1:26 pm PDT */
14:
15: #include "gc_priv.h"
16: #include "gc_mark.h"
17:
18: #ifdef __STDC__
19: void GC_default_same_obj_print_proc(GC_PTR p, GC_PTR q)
20: #else
21: void GC_default_same_obj_print_proc (p, q)
22: GC_PTR p, q;
23: #endif
24: {
25: GC_err_printf2("0x%lx and 0x%lx are not in the same object\n",
26: (unsigned long)p, (unsigned long)q);
27: ABORT("GC_same_obj test failed");
28: }
29:
30: void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR, GC_PTR))
31: = GC_default_same_obj_print_proc;
32:
33: /* Check that p and q point to the same object. Call */
34: /* *GC_same_obj_print_proc if they don't. */
35: /* Returns the first argument. (Return value may be hard */
36: /* to use,due to typing issues. But if we had a suitable */
37: /* preprocessor ...) */
38: /* Succeeds if neither p nor q points to the heap. */
39: /* We assume this is performance critical. (It shouldn't */
40: /* be called by production code, but this can easily make */
41: /* debugging intolerably slow.) */
42: #ifdef __STDC__
43: GC_PTR GC_same_obj(register void *p, register void *q)
44: #else
45: GC_PTR GC_same_obj(p, q)
46: register char *p, *q;
47: #endif
48: {
49: register struct hblk *h;
50: register hdr *hhdr;
51: register ptr_t base, limit;
52: register word sz;
53:
54: if (!GC_is_initialized) GC_init();
55: hhdr = HDR((word)p);
56: if (hhdr == 0) {
57: if (divHBLKSZ((word)p) != divHBLKSZ((word)q)
58: && HDR((word)q) != 0) {
59: goto fail;
60: }
61: return(p);
62: }
63: /* If it's a pointer to the middle of a large object, move it */
64: /* to the beginning. */
65: if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
66: h = HBLKPTR(p) - (word)hhdr;
67: hhdr = HDR(h);
68: while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
69: h = FORWARDED_ADDR(h, hhdr);
70: hhdr = HDR(h);
71: }
72: limit = (ptr_t)((word *)h + HDR_WORDS + hhdr -> hb_sz);
73: if ((ptr_t)p >= limit || (ptr_t)q >= limit || (ptr_t)q < (ptr_t)h ) {
74: goto fail;
75: }
76: return(p);
77: }
78: sz = WORDS_TO_BYTES(hhdr -> hb_sz);
79: if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
80: base = (ptr_t)HBLKPTR(p);
81: limit = base + sz;
82: if ((ptr_t)p >= limit) {
83: goto fail;
84: }
85: } else {
86: # ifdef ALL_INTERIOR_POINTERS
87: register map_entry_type map_entry;
88: register int pdispl;
89:
90: pdispl = HBLKDISPL(p);
91: map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
92: if (map_entry == OBJ_INVALID) {
93: goto fail;
94: } else {
95: base = (char *)((word)p & ~(WORDS_TO_BYTES(1) - 1));
96: base -= WORDS_TO_BYTES(map_entry);
97: }
98: # else
99: register int offset = HBLKDISPL(p) - HDR_BYTES;
100: register word correction = offset % sz;
101:
102: if (HBLKPTR(p) != HBLKPTR(q)) {
103: /* The following computation otherwise fails in this case */
104: goto fail;
105: }
106: base = (ptr_t)p - correction;
107: # endif
108: limit = base + sz;
109: }
110: /* [base, limit) delimits the object containing p, if any. */
111: /* If p is not inside a valid object, then either q is */
112: /* also outside any valid object, or it is outside */
113: /* [base, limit). */
114: if ((ptr_t)q >= limit || (ptr_t)q < base) {
115: goto fail;
116: }
117: return(p);
118: fail:
119: (*GC_same_obj_print_proc)((ptr_t)p, (ptr_t)q);
120: return(p);
121: }
122:
123: #ifdef __STDC__
124: void GC_default_is_valid_displacement_print_proc (GC_PTR p)
125: #else
126: void GC_default_is_valid_displacement_print_proc (p)
127: GC_PTR p;
128: #endif
129: {
130: GC_err_printf1("0x%lx does not point to valid object displacement\n",
131: (unsigned long)p);
132: ABORT("GC_is_valid_displacement test failed");
133: }
134:
135: void (*GC_is_valid_displacement_print_proc) GC_PROTO((GC_PTR)) =
136: GC_default_is_valid_displacement_print_proc;
137:
138: /* Check that if p is a pointer to a heap page, then it points to */
139: /* a valid displacement within a heap object. */
140: /* Uninteresting with ALL_INTERIOR_POINTERS. */
141: /* Always returns its argument. */
142: /* Note that we don't lock, since nothing relevant about the header */
143: /* should change while we have a valid object pointer to the block. */
144: #ifdef __STDC__
145: void * GC_is_valid_displacement(void *p)
146: #else
147: char *GC_is_valid_displacement(p)
148: char *p;
149: #endif
150: {
151: register hdr *hhdr;
152: register word pdispl;
153: register struct hblk *h;
154: register map_entry_type map_entry;
155: register word sz;
156:
157: if (!GC_is_initialized) GC_init();
158: hhdr = HDR((word)p);
159: if (hhdr == 0) return(p);
160: h = HBLKPTR(p);
161: # ifdef ALL_INTERIOR_POINTERS
162: while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
163: h = FORWARDED_ADDR(h, hhdr);
164: hhdr = HDR(h);
165: }
166: # endif
167: if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
168: goto fail;
169: }
170: sz = WORDS_TO_BYTES(hhdr -> hb_sz);
171: pdispl = HBLKDISPL(p);
172: map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
173: if (map_entry == OBJ_INVALID
174: || sz > MAXOBJSZ && (ptr_t)p >= (ptr_t)h + sz) {
175: goto fail;
176: }
177: return(p);
178: fail:
179: (*GC_is_valid_displacement_print_proc)((ptr_t)p);
180: return(p);
181: }
182:
183: #ifdef __STDC__
184: void GC_default_is_visible_print_proc(GC_PTR p)
185: #else
186: void GC_default_is_visible_print_proc(p)
187: GC_PTR p;
188: #endif
189: {
190: GC_err_printf1("0x%lx is not a GC visible pointer location\n",
191: (unsigned long)p);
192: ABORT("GC_is_visible test failed");
193: }
194:
195: void (*GC_is_visible_print_proc) GC_PROTO((GC_PTR p)) =
196: GC_default_is_visible_print_proc;
197:
198: /* Could p be a stack address? */
199: GC_bool GC_on_stack(p)
200: ptr_t p;
201: {
202: # ifdef THREADS
203: return(TRUE);
204: # else
205: int dummy;
206: # ifdef STACK_GROWS_DOWN
207: if ((ptr_t)p >= (ptr_t)(&dummy) && (ptr_t)p < GC_stackbottom ) {
208: return(TRUE);
209: }
210: # else
211: if ((ptr_t)p <= (ptr_t)(&dummy) && (ptr_t)p > GC_stackbottom ) {
212: return(TRUE);
213: }
214: # endif
215: return(FALSE);
216: # endif
217: }
218:
219: /* Check that p is visible */
220: /* to the collector as a possibly pointer containing location. */
221: /* If it isn't invoke *GC_is_visible_print_proc. */
222: /* Returns the argument in all cases. May erroneously succeed */
223: /* in hard cases. (This is intended for debugging use with */
224: /* untyped allocations. The idea is that it should be possible, though */
225: /* slow, to add such a call to all indirect pointer stores.) */
226: /* Currently useless for multithreaded worlds. */
227: #ifdef __STDC__
228: void * GC_is_visible(void *p)
229: #else
230: char *GC_is_visible(p)
231: char *p;
232: #endif
233: {
234: register hdr *hhdr;
235:
236: if ((word)p & (ALIGNMENT - 1)) goto fail;
237: if (!GC_is_initialized) GC_init();
238: # ifdef THREADS
239: hhdr = HDR((word)p);
240: if (hhdr != 0 && GC_base(p) == 0) {
241: goto fail;
242: } else {
243: /* May be inside thread stack. We can't do much. */
244: return(p);
245: }
246: # else
247: /* Check stack first: */
248: if (GC_on_stack(p)) return(p);
249: hhdr = HDR((word)p);
250: if (hhdr == 0) {
251: GC_bool result;
252:
253: if (GC_is_static_root(p)) return(p);
254: /* Else do it again correctly: */
255: # if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \
256: && !defined(SRC_M3)
257: DISABLE_SIGNALS();
258: GC_register_dynamic_libraries();
259: result = GC_is_static_root(p);
260: ENABLE_SIGNALS();
261: if (result) return(p);
262: # endif
263: goto fail;
264: } else {
265: /* p points to the heap. */
266: word descr;
267: ptr_t base = GC_base(p); /* Should be manually inlined? */
268:
269: if (base == 0) goto fail;
270: if (HBLKPTR(base) != HBLKPTR(p)) hhdr = HDR((word)p);
271: descr = hhdr -> hb_descr;
272: retry:
273: switch(descr & DS_TAGS) {
274: case DS_LENGTH:
275: if ((word)((ptr_t)p - (ptr_t)base) > (word)descr) goto fail;
276: break;
277: case DS_BITMAP:
278: if ((ptr_t)p - (ptr_t)base
279: >= WORDS_TO_BYTES(BITMAP_BITS)
280: || ((word)p & (sizeof(word) - 1))) goto fail;
281: if (!((1 << (WORDSZ - ((ptr_t)p - (ptr_t)base) - 1))
282: & descr)) goto fail;
283: break;
284: case DS_PROC:
285: /* We could try to decipher this partially. */
286: /* For now we just punt. */
287: break;
288: case DS_PER_OBJECT:
289: descr = *(word *)((ptr_t)base + (descr & ~DS_TAGS));
290: goto retry;
291: }
292: return(p);
293: }
294: # endif
295: fail:
296: (*GC_is_visible_print_proc)((ptr_t)p);
297: return(p);
298: }
299:
300:
301: GC_PTR GC_pre_incr (p, how_much)
302: GC_PTR *p;
303: size_t how_much;
304: {
305: GC_PTR initial = *p;
306: GC_PTR result = GC_same_obj((GC_PTR)((word)initial + how_much), initial);
307:
308: # ifndef ALL_INTERIOR_POINTERS
309: (void) GC_is_valid_displacement(result);
310: # endif
311: return (*p = result);
312: }
313:
314: GC_PTR GC_post_incr (p, how_much)
315: GC_PTR *p;
316: size_t how_much;
317: {
318: GC_PTR initial = *p;
319: GC_PTR result = GC_same_obj((GC_PTR)((word)initial + how_much), initial);
320:
321: # ifndef ALL_INTERIOR_POINTERS
322: (void) GC_is_valid_displacement(result);
323: # endif
324: *p = result;
325: return(initial);
326: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>