static PN_SIZE pngc_mark_array(Potion *P, register _PN *x, register long n, int forward) { _PN v; PN_SIZE i = 0; struct PNMemory *M = P->mem; while (n--) { v = *x; if (IS_GC_PROTECTED(v) || IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) { v = potion_fwd(v); switch (forward) { case 0: // count only if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) i++; break; case 1: // minor if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; } break; case 2: // major if (!IS_GC_PROTECTED(v) && (IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; } break; } } x++; } return i; }
void potion_test_allocated(CuTest *T) { struct PNMemory *M = P->mem; void *prev = NULL; void *scanptr = (void *)((char *)M->birth_lo + PN_ALIGN(sizeof(struct PNMemory), 8)); while ((PN)scanptr < (PN)M->birth_cur) { if (((struct PNFwd *)scanptr)->fwd != POTION_FWD && ((struct PNFwd *)scanptr)->fwd != POTION_COPIED) { if (((struct PNObject *)scanptr)->vt > PN_TUSER) { vPN(Object) o = (struct PNObject *)scanptr; fprintf(stderr, "error: scanning heap from %p to %p\n", M->birth_lo, M->birth_cur); fprintf(stderr, "%p in %s region\n", scanptr, IS_GC_PROTECTED(scanptr) ? "protected" : IN_BIRTH_REGION(scanptr) ? "birth" : IN_OLDER_REGION(scanptr) ? "older" : "gc"); fprintf(stderr, "%p { uniq:0x%08x vt:0x%08x ivars[0]:0x%08lx type:0x%x}\n", scanptr, o->uniq, o->vt, o->ivars[0], potion_type((PN)scanptr)); fprintf(stderr, "prev %p: size=%d, type:0x%x (%s)\n", prev, potion_type_size(P, prev), potion_type((PN)prev), AS_STR(PN_VTABLE(PN_TYPE((PN)prev)))); #ifdef DEBUG //potion_dump_stack(P); #endif } CuAssert(T, "wrong type for allocated object", ((struct PNObject *)scanptr)->vt <= PN_TUSER); } prev = scanptr; scanptr = (void *)((char *)scanptr + potion_type_size(P, scanptr)); CuAssert(T, "allocated object goes beyond GC pointer", (PN)scanptr <= (PN)M->birth_cur); } }
ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS static PN_SIZE pngc_mark_array(Potion *P, register _PN *x, register long n, int type) { _PN v; PN_SIZE i = 0; struct PNMemory *M = P->mem; while (n--) { v = *x; if (IS_GC_PROTECTED(v) || IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) { v = potion_fwd(v); switch (type) { case 0: // count only if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) { i++; DBG_Gv(P,"GC mark count only %p %6x\n", x, PN_TYPE(*x)); } break; case 1: // minor if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; DBG_Gv(P,"GC mark minor %p -> 0x%lx %6x\n", x, v, PN_TYPE(*x)); } break; case 2: // major if (!IS_GC_PROTECTED(v) && (IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; DBG_Gv(P,"GC mark major %p -> 0x%lx %6x\n", x, v, PN_TYPE(*x)); } break; } } x++; } return i; }
void potion_dump_stack(Potion *P) { long n; PN *end, *ebp, *start = P->mem->cstack; struct PNMemory *M = P->mem; POTION_ESP(&end); POTION_EBP(&ebp); #if POTION_STACK_DIR > 0 n = end - start; #else n = start - end + 1; start = end; end = M->cstack; #endif printf("-- dumping %ld stack from %p to %p --\n", n, start, end); printf(" ebp = %p, *ebp = %lx\n", ebp, *ebp); while (n--) { vPN(Object) o = (struct PNObject*)*start; printf(" stack(%ld) = %p: %lx", n, start, *start); if (IS_GC_PROTECTED(*start)) printf(" vt=%x gc", PN_TYPE(o)); else if (IN_BIRTH_REGION(*start)) printf(" vt=%x gc(0)", PN_TYPE(o)); else if (IN_OLDER_REGION(*start)) printf(" vt=%x gc(1)", PN_TYPE(o)); if (*start == 0) printf(" nil\n"); else if (*start & 1) printf(" %ld INT\n", PN_INT(*start)); else if (*start & 2) printf(" %s BOOL\n", *start == 2 ? "false" : "true"); else printf(" \n"); start++; } }