Skip to content

Commit

Permalink
Load page count from region
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed May 16, 2016
1 parent e803760 commit 1bf998a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/gc-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static void clear_mark(int bits)
region_t *region = &regions[h];
if (!region->pages)
break;
for (int pg_i = 0; pg_i < REGION_PG_COUNT/32; pg_i++) {
for (int pg_i = 0; pg_i < region->pg_cnt / 32; pg_i++) {
uint32_t line = region->freemap[pg_i];
if (!!~line) {
for (int j = 0; j < 32; j++) {
Expand Down
27 changes: 15 additions & 12 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,20 +462,20 @@ static NOINLINE void *malloc_page(void)
region->meta = (jl_gc_pagemeta_t*)(mem + pages_sz +freemap_sz);
region->lb = 0;
region->ub = 0;
region->pg_cnt = REGION_PG_COUNT;
#ifdef _OS_WINDOWS_
VirtualAlloc(region->freemap, REGION_PG_COUNT / 8,
VirtualAlloc(region->freemap, region->pg_cnt / 8,
MEM_COMMIT, PAGE_READWRITE);
VirtualAlloc(region->meta,
REGION_PG_COUNT * sizeof(jl_gc_pagemeta_t),
VirtualAlloc(region->meta, region->pg_cnt * sizeof(jl_gc_pagemeta_t),
MEM_COMMIT, PAGE_READWRITE);
#endif
memset(region->freemap, 0xff, REGION_PG_COUNT/8);
memset(region->freemap, 0xff, region->pg_cnt / 8);
}
for (i = region->lb; i < REGION_PG_COUNT/32; i++) {
for (i = region->lb; i < region->pg_cnt / 32; i++) {
if (region->freemap[i])
break;
}
if (i == REGION_PG_COUNT/32) {
if (i == region->pg_cnt / 32) {
// region full
region_i++;
continue;
Expand Down Expand Up @@ -516,12 +516,15 @@ static void free_page(void *p)
{
int pg_idx = -1;
int i;
for(i = 0; i < REGION_COUNT && regions[i].pages != NULL; i++) {
pg_idx = page_index(&regions[i], p);
if (pg_idx >= 0 && pg_idx < REGION_PG_COUNT) break;
region_t *region = regions;
for (i = 0; i < REGION_COUNT && regions[i].pages != NULL; i++) {
region = &regions[i];
pg_idx = page_index(region, p);
if (pg_idx >= 0 && pg_idx < region->pg_cnt) {
break;
}
}
assert(i < REGION_COUNT && regions[i].pages != NULL);
region_t *region = &regions[i];
assert(i < REGION_COUNT && region->pages != NULL);
uint32_t msk = (uint32_t)(1 << (pg_idx % 32));
assert(!(region->freemap[pg_idx/32] & msk));
region->freemap[pg_idx/32] ^= msk;
Expand All @@ -534,7 +537,7 @@ static void free_page(void *p)
decommit_size = jl_page_size;
p = (void*)((uintptr_t)region->pages[pg_idx].data & ~(jl_page_size - 1)); // round down to the nearest page
pg_idx = page_index(region, p);
if (pg_idx + n_pages > REGION_PG_COUNT) goto no_decommit;
if (pg_idx + n_pages > region->pg_cnt) goto no_decommit;
for (; n_pages--; pg_idx++) {
msk = (uint32_t)(1 << ((pg_idx % 32)));
if (!(region->freemap[pg_idx/32] & msk)) goto no_decommit;
Expand Down
17 changes: 10 additions & 7 deletions src/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ typedef struct {
// Blocks: osize * n
// Tag: sizeof_jl_taggedvalue_t
// Data: <= osize - sizeof_jl_taggedvalue_t
jl_gc_page_t *pages; // [REGION_PG_COUNT] // must be first, to preserve page alignment
uint32_t *freemap; // [REGION_PG_COUNT/32]
jl_gc_pagemeta_t *meta; // [REGION_PG_COUNT]
jl_gc_page_t *pages; // [pg_cnt]; must be first, to preserve page alignment
uint32_t *freemap; // [pg_cnt / 32]
jl_gc_pagemeta_t *meta; // [pg_cnt]
int pg_cnt;
// store a lower bound of the first free page in each region
int lb;
// an upper bound of the last non-free page
Expand Down Expand Up @@ -287,10 +288,12 @@ STATIC_INLINE region_t *find_region(void *ptr, int maybe)
{
// on 64bit systems we could probably use a single region and remove this loop
for (int i = 0; i < REGION_COUNT && regions[i].pages; i++) {
char *begin = regions[i].pages->data;
char *end = begin + sizeof(jl_gc_page_t) * REGION_PG_COUNT;
if ((char*)ptr >= begin && (char*)ptr <= end)
return &regions[i];
region_t *region = &regions[i];
char *begin = region->pages->data;
char *end = begin + region->pg_cnt * sizeof(jl_gc_page_t);
if ((char*)ptr >= begin && (char*)ptr <= end) {
return region;
}
}
(void)maybe;
assert(maybe && "find_region failed");
Expand Down

0 comments on commit 1bf998a

Please sign in to comment.