Skip to content

Commit

Permalink
Page sweep cleanup.
Browse files Browse the repository at this point in the history
* Now that the page metadata is accurate, we don't need to backoff when we
  sweep an empty page anymore.
* Remove `MEMDEBUG` in page sweep since it's not used.
  • Loading branch information
yuyichao committed Jun 3, 2016
1 parent bd27c01 commit af3e441
Showing 1 changed file with 30 additions and 43 deletions.
73 changes: 30 additions & 43 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,20 +809,36 @@ int64_t lazy_freed_pages = 0;
// Returns pointer to terminal pointer of list rooted at *pfl.
static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl, int sweep_full, int osize)
{
gcval_t **prev_pfl = pfl;
gcval_t *v;
size_t old_nfree = 0, nfree = 0;
int obj_per_page = (GC_PAGE_SZ - GC_PAGE_OFFSET)/osize;
char *data = pg->data;
uint8_t *ages = pg->ages;
v = (gcval_t*)(data + GC_PAGE_OFFSET);
gcval_t *v = (gcval_t*)(data + GC_PAGE_OFFSET);
char *lim = (char*)v + GC_PAGE_SZ - GC_PAGE_OFFSET - osize;
old_nfree += pg->nfree;
size_t old_nfree = pg->nfree;
size_t nfree;

int freedall = 1;
int pg_skpd = 1;
if (!pg->has_marked)
goto free_page;
if (!pg->has_marked) {
// lazy version: (empty) if the whole page was already unused, free it
// eager version: (freedall) free page as soon as possible
// the eager one uses less memory.
// FIXME - need to do accounting on a per-thread basis
// on quick sweeps, keep a few pages empty but allocated for performance
if (!sweep_full && lazy_freed_pages <= default_collect_interval / GC_PAGE_SZ) {
gcval_t *begin = reset_page(p, pg, 0);
gcval_t **pend = (gcval_t**)((char*)begin + ((int)pg->nfree - 1)*osize);
gcval_t *npg = p->newpages;
*pend = npg;
p->newpages = begin;
begin->next = (gcval_t*)0;
lazy_freed_pages++;
}
else {
jl_gc_free_page(data);
}
nfree = (GC_PAGE_SZ - GC_PAGE_OFFSET) / osize;
goto done;
}
// For quick sweep, we might be able to skip the page if the page doesn't
// have any young live cell before marking.
if (!sweep_full && !pg->has_young) {
Expand All @@ -832,10 +848,11 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
// is stored in its metadata
if (pg->fl_begin_offset != (uint16_t)-1) {
*pfl = page_pfl_beg(pg);
pfl = prev_pfl = (gcval_t**)page_pfl_end(pg);
pfl = (gcval_t**)page_pfl_end(pg);
}
freedall = 0;
goto free_page;
nfree = pg->nfree;
goto done;
}
}

Expand Down Expand Up @@ -894,41 +911,11 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
pg->prev_nold = prev_nold;
}
}
free_page:
// lazy version: (empty) if the whole page was already unused, free it
// eager version: (freedall) free page as soon as possible
// the eager one uses less memory.
if (freedall) {
// FIXME - need to do accounting on a per-thread basis
// on quick sweeps, keep a few pages empty but allocated for performance
if (!sweep_full && lazy_freed_pages <= default_collect_interval/GC_PAGE_SZ) {
gcval_t *begin = reset_page(p, pg, 0);
gcval_t **pend = (gcval_t**)((char*)begin + ((int)pg->nfree - 1)*osize);
gcval_t *npg = p->newpages;
*pend = npg;
p->newpages = begin;
begin->next = (gcval_t*)0;
lazy_freed_pages++;
pfl = prev_pfl;
}
else {
pfl = prev_pfl;
#ifdef MEMDEBUG
memset(pg->data, 0xbb, GC_PAGE_SZ);
#endif
jl_gc_free_page(data);
#ifdef MEMDEBUG
memset(pg, 0xbb, sizeof(jl_gc_pagemeta_t));
#endif
}
nfree += obj_per_page;
}
else {
nfree += pg->nfree;
}
nfree = pg->nfree;

done:
gc_time_count_page(freedall, pg_skpd);
gc_num.freed += (nfree - old_nfree)*osize;
gc_num.freed += (nfree - old_nfree) * osize;
return pfl;
}

Expand Down

0 comments on commit af3e441

Please sign in to comment.