[gc][bugfix] sweeping failed when the heap gets completely

exhausted (i.e. all blocks' size are zero)
This commit is contained in:
Yuichi Nishiwaki 2013-11-29 12:05:22 +09:00
parent f03a153774
commit 21f2c58a53
2 changed files with 8 additions and 8 deletions

View File

@ -16,7 +16,7 @@ union header {
}; };
struct pic_heap { struct pic_heap {
union header base, *freep; union header base, *freep, *endp;
size_t heap_size; size_t heap_size;
}; };

View File

@ -27,13 +27,11 @@ init_heap(struct pic_heap *heap)
heap->base.s.mark = PIC_GC_UNMARK; heap->base.s.mark = PIC_GC_UNMARK;
heap->freep = heap->base.s.ptr; heap->freep = heap->base.s.ptr;
heap->freep->s.size = nu - 1; heap->freep->s.size = nu;
heap->freep->s.ptr = heap->freep + heap->freep->s.size; heap->freep->s.ptr = &heap->base;
heap->freep->s.mark = PIC_GC_UNMARK; heap->freep->s.mark = PIC_GC_UNMARK;
heap->freep->s.ptr->s.size = 0; heap->endp = heap->freep + heap->freep->s.size;
heap->freep->s.ptr->s.ptr = &heap->base;
heap->freep->s.ptr->s.mark = PIC_GC_UNMARK;
#if GC_DEBUG #if GC_DEBUG
printf("freep = %p\n", heap->freep); printf("freep = %p\n", heap->freep);
@ -482,9 +480,10 @@ gc_sweep_phase(pic_state *pic)
basep = &pic->heap->base; basep = &pic->heap->base;
for (bp = basep->s.ptr; bp != basep; bp = bp->s.ptr) { for (bp = basep->s.ptr; bp != basep; bp = bp->s.ptr) {
if (bp->s.size == 0) /* end of page */
continue;
for (p = bp + bp->s.size; p != bp->s.ptr; p += p->s.size) { for (p = bp + bp->s.size; p != bp->s.ptr; p += p->s.size) {
if (p == pic->heap->endp) {
goto end;
}
if (! gc_is_marked(p)) { if (! gc_is_marked(p)) {
if (s == NULL) { if (s == NULL) {
s = p; s = p;
@ -498,6 +497,7 @@ gc_sweep_phase(pic_state *pic)
gc_unmark(p); gc_unmark(p);
} }
} }
end:
/* free! */ /* free! */
while (s) { while (s) {