Пример #1
0
static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero)
{
  GC_Weak_Box *wb;

  wb = gc->weak_boxes[is_late];
  while (wb) {
    if (force_zero || !is_marked(gc, wb->val)) {
      wb->val = NULL;
      if (wb->secondary_erase) {
        void **p;
        mpage *page;

        /* it's possible for the secondary to be in an old generation
           and therefore on an mprotected page: */
        page = pagemap_find_page(gc->page_maps, wb->secondary_erase);
        if (page->mprotected) {
          page->mprotected = 0;
          mmu_write_unprotect_page(gc->mmu, page->addr, APAGE_SIZE);
          GC_MP_CNT_INC(mp_mark_cnt);
        }

        p = (void **)GC_resolve2(wb->secondary_erase, gc);
        *(p + wb->soffset) = NULL;
        wb->secondary_erase = NULL;
      }
    }
    wb = wb->next;
  }

  /* reset, in case we have a second round */
  gc->weak_boxes[is_late] = NULL;
}
Пример #2
0
static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc, int fuel)
{
  GC_Weak_Box *wb;
  int num_gen0;

  if (from_inc) {
    wb = gc->inc_weak_boxes[is_late];
    num_gen0 = 0;
  } else {
    wb = append_weak_boxes(gc->weak_boxes[is_late],
                           gc->bp_weak_boxes[is_late],
                           &num_gen0);
    if (gc->gc_full || !gc->started_incremental)
      num_gen0 = 0;
  }

  while (wb) {
    GC_ASSERT(is_marked(gc, wb));
    if (!wb->val) {
      /* nothing to do */
    } else if (force_zero || !is_marked(gc, wb->val)) {
      wb->val = NULL;
      if (wb->secondary_erase) {
        void **p;
        mpage *page;

        /* it's possible for the secondary to be in an old generation
           and therefore on an mprotected page: */
        page = pagemap_find_page(gc->page_maps, wb->secondary_erase);
        if (page->mprotected) {
          page->mprotected = 0;
          mmu_write_unprotect_page(gc->mmu, page->addr, APAGE_SIZE, page_mmu_type(page), &page->mmu_src_block);
          page->reprotect_next = gc->reprotect_next;
          gc->reprotect_next = page;
          page->reprotect = 1;
        }
        p = (void **)GC_resolve2(wb->secondary_erase, gc);
        *(p + wb->soffset) = NULL;
        wb->secondary_erase = NULL;
      }
    } else {
      wb->val = GC_resolve2(wb->val, gc);
    }
    if (num_gen0 > 0) {
      if (!is_in_generation_half(gc, wb)) {
        /* For incremental mode, preserve this weak box
           in the incremental list for re-checking later. */
        check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]);
        wb->inc_next = gc->inc_weak_boxes[is_late];
        gc->inc_weak_boxes[is_late] = wb;
      }
    }
    if (from_inc) {
      GC_Weak_Box *next;
      next = wb->inc_next;
      wb->inc_next = gc->weak_incremental_done;
      wb = next;
    } else
      wb = wb->next;

    num_gen0--;

    if (fuel >= 0) {
      if (fuel > 0)
        fuel--;
      else {
        GC_ASSERT(from_inc);
        gc->inc_weak_boxes[is_late] = wb;
        return 0;
      }
    }
  }

  /* reset, in case we have a second round */
  if (from_inc) {
    gc->inc_weak_boxes[is_late] = NULL;
  } else {
    gc->weak_boxes[is_late] = NULL;
    gc->bp_weak_boxes[is_late] = NULL;
  }

  return fuel;
}