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; }
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; }