Check that p and q point to the same object. Call */ GC_same_obj_print_proc if they don't. */ Returns the first argument. (Return value may be hard */ to use,due to typing issues. But if we had a suitable */ preprocessor ...) */ Succeeds if neither p nor q points to the heap. */ We assume this is performance critical. (It shouldn't */ be called by production code, but this can easil
| 37 | /* be called by production code, but this can easily make */ |
| 38 | /* debugging intolerably slow.) */ |
| 39 | void * GC_same_obj(void *p, void *q) |
| 40 | { |
| 41 | struct hblk *h; |
| 42 | hdr *hhdr; |
| 43 | ptr_t base, limit; |
| 44 | word sz; |
| 45 | |
| 46 | if (!GC_is_initialized) GC_init(); |
| 47 | hhdr = HDR((word)p); |
| 48 | if (hhdr == 0) { |
| 49 | if (divHBLKSZ((word)p) != divHBLKSZ((word)q) |
| 50 | && HDR((word)q) != 0) { |
| 51 | goto fail; |
| 52 | } |
| 53 | return(p); |
| 54 | } |
| 55 | /* If it's a pointer to the middle of a large object, move it */ |
| 56 | /* to the beginning. */ |
| 57 | if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { |
| 58 | h = HBLKPTR(p) - (word)hhdr; |
| 59 | hhdr = HDR(h); |
| 60 | while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { |
| 61 | h = FORWARDED_ADDR(h, hhdr); |
| 62 | hhdr = HDR(h); |
| 63 | } |
| 64 | limit = (ptr_t)h + hhdr -> hb_sz; |
| 65 | if ((ptr_t)p >= limit || (ptr_t)q >= limit || (ptr_t)q < (ptr_t)h ) { |
| 66 | goto fail; |
| 67 | } |
| 68 | return(p); |
| 69 | } |
| 70 | sz = hhdr -> hb_sz; |
| 71 | if (sz > MAXOBJBYTES) { |
| 72 | base = (ptr_t)HBLKPTR(p); |
| 73 | limit = base + sz; |
| 74 | if ((ptr_t)p >= limit) { |
| 75 | goto fail; |
| 76 | } |
| 77 | } else { |
| 78 | size_t offset; |
| 79 | size_t pdispl = HBLKDISPL(p); |
| 80 | |
| 81 | offset = pdispl % sz; |
| 82 | if (HBLKPTR(p) != HBLKPTR(q)) goto fail; |
| 83 | /* W/o this check, we might miss an error if */ |
| 84 | /* q points to the first object on a page, and */ |
| 85 | /* points just before the page. */ |
| 86 | base = (ptr_t)p - offset; |
| 87 | limit = base + sz; |
| 88 | } |
| 89 | /* [base, limit) delimits the object containing p, if any. */ |
| 90 | /* If p is not inside a valid object, then either q is */ |
| 91 | /* also outside any valid object, or it is outside */ |
| 92 | /* [base, limit). */ |
| 93 | if ((ptr_t)q >= limit || (ptr_t)q < base) { |
| 94 | goto fail; |
| 95 | } |
| 96 | return(p); |
no test coverage detected