Example #1
0
void gc_test_alloc4(CuTest *T) {
  PN ptr = (PN)potion_gc_alloc(P, PN_TUSER, 16);
  PN ptr2 = (PN)potion_gc_alloc(P, PN_TUSER, 16);
  PN ptr3 = (PN)potion_gc_alloc(P, PN_TUSER, 16);
  PN ptr4 = (PN)potion_gc_alloc(P, PN_TUSER, 16);
  PN_SIZE count = potion_mark_stack(P, 0);
  CuAssert(T, "couldn't allocate 16 bytes from GC", PN_IS_PTR(ptr));
  CuAssert(T, "couldn't allocate 16 bytes from GC", PN_IS_PTR(ptr2));
  CuAssert(T, "couldn't allocate 16 bytes from GC", PN_IS_PTR(ptr3));
  CuAssert(T, "couldn't allocate 16 bytes from GC", PN_IS_PTR(ptr4));
  CuAssertIntEquals(T, "four allocations should be found", 5, count);
}
Example #2
0
void gc_test_forward(CuTest *T) {
  PN_SIZE count;
  char *fj = "frances johnson.";
  PN ptr = potion_data_alloc(P, 16);
  register unsigned long old = ptr & 0xFFFF;
  memcpy(((struct PNData *)ptr)->data, fj, 16);

  count = potion_mark_stack(P, 1);
  CuAssert(T, "copied location identical to original", (old & 0xFFFF) != ptr);
  CuAssertIntEquals(T, "copied object not still PN_TUSER", ((struct PNData *)ptr)->vt, PN_TUSER);
  CuAssert(T, "copied data not identical to original",
    strncmp(((struct PNData *)ptr)->data, fj, 16) == 0);
}
Example #3
0
//
// Both this function and potion_gc_major embody a simple
// Cheney loop (also called a "two-finger collector.")
// http://en.wikipedia.org/wiki/Cheney%27s_algorithm
// (Again, many thanks to Basile Starynkevitch for
// his tutelage in this matter.)
//
static int potion_gc_minor(Potion *P, int sz) {
  struct PNMemory *M = P->mem;
  void *scanptr = 0;
  void **storead = 0, **wb = 0;

  if (sz < 0)
    sz = 0;
  else if (sz >= POTION_MAX_BIRTH_SIZE)
    return POTION_NO_MEM;

  scanptr = (void *) M->old_cur;
  info("running gc_minor\n"
    "(young: %p -> %p = %ld)\n"
    "(old: %p -> %p = %ld)\n"
    "(storeptr len = %ld)\n",
    M->birth_lo, M->birth_hi, (long)(M->birth_hi - M->birth_lo),
    M->old_lo, M->old_hi, (long)(M->old_hi - M->old_lo),
    (long)((void *)M->birth_hi - (void *)M->birth_storeptr));
  potion_mark_stack(P, 1);

  GC_MINOR_STRINGS();

  wb = (void **)M->birth_storeptr;
  for (storead = wb; storead < (void **)M->birth_hi; storead++) {
    PN v = (PN)*storead;
    if (PN_IS_PTR(v))
      potion_mark_minor(P, (const struct PNObject *)v);
  }
  storead = 0;

  while ((PN)scanptr < (PN)M->old_cur)
    scanptr = potion_mark_minor(P, scanptr);
  scanptr = 0;

  sz += 2 * POTION_PAGESIZE;
  sz = max(sz, potion_birth_suggest(sz, M->old_lo, M->old_cur));

  sz = NEW_BIRTH_REGION(M, wb, sz);
  M->minors++;

  info("(new young: %p -> %p = %d)\n", M->birth_lo, M->birth_hi, (long)(M->birth_hi - M->birth_lo));
  return POTION_OK;
}
Example #4
0
static int potion_gc_major(Potion *P, int siz) {
  struct PNMemory *M = P->mem;
  void *prevoldlo = 0;
  void *prevoldhi = 0;
  void *prevoldcur = 0;
  void *newold = 0;
  void *protptr = (void *)M + PN_ALIGN(sizeof(struct PNMemory), 8);
  void *scanptr = 0;
  void **wb = 0;
  int birthest = 0;
  int birthsiz = 0;
  int newoldsiz = 0;
  int oldsiz = 0;

  if (siz < 0)
    siz = 0;
  else if (siz >= POTION_MAX_BIRTH_SIZE)
    return POTION_NO_MEM;

  prevoldlo = (void *)M->old_lo;
  prevoldhi = (void *)M->old_hi;
  prevoldcur = (void *)M->old_cur;

  info("running gc_major\n"
    "(young: %p -> %p = %ld)\n"
    "(old: %p -> %p = %ld)\n",
    M->birth_lo, M->birth_hi, (long)(M->birth_hi - M->birth_lo),
    M->old_lo, M->old_hi, (long)(M->old_hi - M->old_lo));
  birthest = potion_birth_suggest(siz, prevoldlo, prevoldcur);
  newoldsiz = (((char *)prevoldcur - (char *)prevoldlo) + siz + birthest +
    POTION_GC_THRESHOLD + 16 * POTION_PAGESIZE) + ((char *)M->birth_cur - (char *)M->birth_lo);
  newold = pngc_page_new(&newoldsiz, 0);
  M->old_cur = scanptr = newold + (sizeof(PN) * 2);
  info("(new old: %p -> %p = %d)\n", newold, (char *)newold + newoldsiz, newoldsiz);

  potion_mark_stack(P, 2);

  wb = (void **)M->birth_storeptr;
  if (M->birth_lo != M) {
    while ((PN)protptr < (PN)M->protect)
      protptr = potion_mark_major(P, protptr);
  }

  while ((PN)scanptr < (PN)M->old_cur)
    scanptr = potion_mark_major(P, scanptr);
  scanptr = 0;

  GC_MAJOR_STRINGS();

  pngc_page_delete((void *)prevoldlo, (char *)prevoldhi - (char *)prevoldlo);
  prevoldlo = 0;
  prevoldhi = 0;
  prevoldcur = 0;

  birthsiz = NEW_BIRTH_REGION(M, wb, siz + birthest);
  oldsiz = ((char *)M->old_cur - (char *)newold) +
    (birthsiz + 2 * birthest + 4 * POTION_PAGESIZE);
  oldsiz = PN_ALIGN(oldsiz, POTION_PAGESIZE);
  if (oldsiz < newoldsiz) {
    pngc_page_delete((void *)newold + oldsiz, newoldsiz - oldsiz);
    newoldsiz = oldsiz;
  }

  M->old_lo = newold;
  M->old_hi = (char *)newold + newoldsiz;
  M->majors++;

  newold = 0;

  return POTION_OK;
}
Example #5
0
//
// everything allocated in alloc1 and alloc4 tests goes out of scope, so will
// not be moved to the old generation. data in the `forward` test will be copied.
//
void gc_test_alloc1(CuTest *T) {
  PN ptr = (PN)potion_gc_alloc(P, PN_TUSER, 16);
  PN_SIZE count = potion_mark_stack(P, 0);
  CuAssert(T, "couldn't allocate 16 bytes from GC", PN_IS_PTR(ptr));
  CuAssertIntEquals(T, "only one allocation should be found", 2, count);
}