Skip to content

Commit 3d93685

Browse files
committed
Store pointer to the actual memory in region_t increase region count
1 parent 4579353 commit 3d93685

File tree

3 files changed

+60
-50
lines changed

3 files changed

+60
-50
lines changed

src/gc-debug.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ static void clear_mark(int bits)
130130
}
131131

132132
for (int h = 0; h < REGION_COUNT; h++) {
133-
region_t *region = regions[h];
134-
if (!region) break;
133+
region_t *region = &regions[h];
134+
if (!region->pages)
135+
break;
135136
for (int pg_i = 0; pg_i < REGION_PG_COUNT/32; pg_i++) {
136137
uint32_t line = region->freemap[pg_i];
137138
if (!!~line) {

src/gc.c

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,7 @@ jl_mutex_t finalizers_lock;
4646
jl_gc_num_t gc_num = {0,0,0,0,0,0,0,0,0,0,0,0,0};
4747
static size_t last_long_collect_interval;
4848

49-
region_t *regions[REGION_COUNT] = {NULL};
50-
// store a lower bound of the first free page in each region
51-
int regions_lb[REGION_COUNT] = {0};
52-
// an upper bound of the last non-free page
53-
int regions_ub[REGION_COUNT] = {REGION_PG_COUNT/32-1};
49+
region_t regions[REGION_COUNT];
5450

5551
#ifndef JULIA_ENABLE_THREADING
5652
static jl_thread_heap_t _jl_thread_heap;
@@ -436,11 +432,15 @@ static NOINLINE void *malloc_page(void)
436432
int region_i = 0;
437433
JL_LOCK_NOGC(&pagealloc_lock);
438434
while(region_i < REGION_COUNT) {
439-
region = regions[region_i];
440-
if (region == NULL) {
441-
size_t alloc_size = sizeof(region_t);
435+
region = &regions[region_i];
436+
if (region->pages == NULL) {
437+
const size_t pages_sz = sizeof(jl_gc_page_t) * REGION_PG_COUNT;
438+
const size_t freemap_sz = sizeof(uint32_t) * REGION_PG_COUNT / 32;
439+
const size_t meta_sz = sizeof(jl_gc_pagemeta_t) * REGION_PG_COUNT;
440+
size_t alloc_size = pages_sz + freemap_sz + meta_sz;
442441
#ifdef _OS_WINDOWS_
443-
char *mem = (char*)VirtualAlloc(NULL, sizeof(region_t) + GC_PAGE_SZ, MEM_RESERVE, PAGE_READWRITE);
442+
char *mem = (char*)VirtualAlloc(NULL, alloc_size + GC_PAGE_SZ,
443+
MEM_RESERVE, PAGE_READWRITE);
444444
#else
445445
if (GC_PAGE_SZ > jl_page_size)
446446
alloc_size += GC_PAGE_SZ;
@@ -453,23 +453,27 @@ static NOINLINE void *malloc_page(void)
453453
abort();
454454
}
455455
if (GC_PAGE_SZ > jl_page_size) {
456-
// round data pointer up to the nearest gc_page_data-aligned boundary
457-
// if mmap didn't already do so
458-
alloc_size += GC_PAGE_SZ;
459-
region = (region_t*)((char*)gc_page_data(mem + GC_PAGE_SZ - 1));
460-
}
461-
else {
462-
region = (region_t*)mem;
456+
// round data pointer up to the nearest gc_page_data-aligned
457+
// boundary if mmap didn't already do so.
458+
mem = (char*)gc_page_data(mem + GC_PAGE_SZ - 1);
463459
}
460+
region->pages = (jl_gc_page_t*)mem;
461+
region->freemap = (uint32_t*)(mem + pages_sz);
462+
region->meta = (jl_gc_pagemeta_t*)(mem + pages_sz +freemap_sz);
463+
region->lb = 0;
464+
region->ub = 0;
464465
#ifdef _OS_WINDOWS_
465-
VirtualAlloc(region->freemap, REGION_PG_COUNT/8, MEM_COMMIT, PAGE_READWRITE);
466-
VirtualAlloc(region->meta, REGION_PG_COUNT*sizeof(jl_gc_pagemeta_t), MEM_COMMIT, PAGE_READWRITE);
466+
VirtualAlloc(region->freemap, REGION_PG_COUNT / 8,
467+
MEM_COMMIT, PAGE_READWRITE);
468+
VirtualAlloc(region->meta,
469+
REGION_PG_COUNT * sizeof(jl_gc_pagemeta_t),
470+
MEM_COMMIT, PAGE_READWRITE);
467471
#endif
468472
memset(region->freemap, 0xff, REGION_PG_COUNT/8);
469-
regions[region_i] = region;
470473
}
471-
for(i = regions_lb[region_i]; i < REGION_PG_COUNT/32; i++) {
472-
if (region->freemap[i]) break;
474+
for (i = region->lb; i < REGION_PG_COUNT/32; i++) {
475+
if (region->freemap[i])
476+
break;
473477
}
474478
if (i == REGION_PG_COUNT/32) {
475479
// region full
@@ -483,10 +487,10 @@ static NOINLINE void *malloc_page(void)
483487
gc_debug_critical_error();
484488
abort();
485489
}
486-
if (regions_lb[region_i] < i)
487-
regions_lb[region_i] = i;
488-
if (regions_ub[region_i] < i)
489-
regions_ub[region_i] = i;
490+
if (region->lb < i)
491+
region->lb = i;
492+
if (region->ub < i)
493+
region->ub = i;
490494

491495
#if defined(_COMPILER_MINGW_)
492496
int j = __builtin_ffs(region->freemap[i]) - 1;
@@ -512,12 +516,12 @@ static void free_page(void *p)
512516
{
513517
int pg_idx = -1;
514518
int i;
515-
for(i = 0; i < REGION_COUNT && regions[i] != NULL; i++) {
516-
pg_idx = page_index(regions[i], p);
519+
for(i = 0; i < REGION_COUNT && regions[i].pages != NULL; i++) {
520+
pg_idx = page_index(&regions[i], p);
517521
if (pg_idx >= 0 && pg_idx < REGION_PG_COUNT) break;
518522
}
519-
assert(i < REGION_COUNT && regions[i] != NULL);
520-
region_t *region = regions[i];
523+
assert(i < REGION_COUNT && regions[i].pages != NULL);
524+
region_t *region = &regions[i];
521525
uint32_t msk = (uint32_t)(1 << (pg_idx % 32));
522526
assert(!(region->freemap[pg_idx/32] & msk));
523527
region->freemap[pg_idx/32] ^= msk;
@@ -542,7 +546,8 @@ static void free_page(void *p)
542546
madvise(p, decommit_size, MADV_DONTNEED);
543547
#endif
544548
no_decommit:
545-
if (regions_lb[i] > pg_idx/32) regions_lb[i] = pg_idx/32;
549+
if (region->lb > pg_idx / 32)
550+
region->lb = pg_idx / 32;
546551
current_pg_count--;
547552
}
548553

@@ -932,12 +937,12 @@ static int page_done = 0;
932937
static gcval_t **sweep_page(pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl,int,int);
933938
static void sweep_pool_region(gcval_t ***pfl, int region_i, int sweep_mask)
934939
{
935-
region_t *region = regions[region_i];
940+
region_t *region = &regions[region_i];
936941

937942
// the actual sweeping
938943
int ub = 0;
939-
int lb = regions_lb[region_i];
940-
for (int pg_i = 0; pg_i <= regions_ub[region_i]; pg_i++) {
944+
int lb = region->lb;
945+
for (int pg_i = 0; pg_i <= region->ub; pg_i++) {
941946
uint32_t line = region->freemap[pg_i];
942947
if (!!~line) {
943948
ub = pg_i;
@@ -958,8 +963,8 @@ static void sweep_pool_region(gcval_t ***pfl, int region_i, int sweep_mask)
958963
lb = pg_i;
959964
}
960965
}
961-
regions_ub[region_i] = ub;
962-
regions_lb[region_i] = lb;
966+
region->ub = ub;
967+
region->lb = lb;
963968
}
964969

965970
// Returns pointer to terminal pointer of list rooted at *pfl.
@@ -1145,7 +1150,7 @@ static int gc_sweep_inc(int sweep_mask)
11451150
}
11461151

11471152
for (int i = 0; i < REGION_COUNT; i++) {
1148-
if (regions[i])
1153+
if (regions[i].pages)
11491154
/*finished &= */sweep_pool_region(pfl, i, sweep_mask);
11501155
}
11511156

@@ -2119,7 +2124,7 @@ void jl_print_gc_stats(JL_STREAM *s)
21192124
(int)(total_fin_time * 100 / gc_num.total_time));
21202125
}
21212126
int i = 0;
2122-
while (i < REGION_COUNT && regions[i]) i++;
2127+
while (i < REGION_COUNT && regions[i].pages) i++;
21232128
jl_printf(s, "max allocated regions : %d\n", i);
21242129
struct mallinfo mi = mallinfo();
21252130
jl_printf(s, "malloc size\t%d MB\n", mi.uordblks/1024/1024);

src/gc.h

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ extern "C" {
4848
#else
4949
#define REGION_PG_COUNT 8*4096 // 512M
5050
#endif
51-
#define REGION_COUNT 8
51+
// 8G * 32768 = 2^48
52+
// It's really unlikely that we'll actually allocate that much though...
53+
#define REGION_COUNT 32768
5254

5355
#define jl_buff_tag ((uintptr_t)0x4eade800)
5456
#define jl_malloc_tag ((void*)0xdeadaa01)
@@ -189,9 +191,13 @@ typedef struct {
189191
// Blocks: osize * n
190192
// Tag: sizeof_jl_taggedvalue_t
191193
// Data: <= osize - sizeof_jl_taggedvalue_t
192-
jl_gc_page_t pages[REGION_PG_COUNT]; // must be first, to preserve page alignment
193-
uint32_t freemap[REGION_PG_COUNT/32];
194-
jl_gc_pagemeta_t meta[REGION_PG_COUNT];
194+
jl_gc_page_t *pages; // [REGION_PG_COUNT] // must be first, to preserve page alignment
195+
uint32_t *freemap; // [REGION_PG_COUNT/32]
196+
jl_gc_pagemeta_t *meta; // [REGION_PG_COUNT]
197+
// store a lower bound of the first free page in each region
198+
int lb;
199+
// an upper bound of the last non-free page
200+
int ub;
195201
} region_t
196202
;
197203

@@ -237,9 +243,7 @@ typedef struct {
237243
extern jl_mutex_t pagealloc_lock;
238244
extern jl_mutex_t finalizers_lock;
239245
extern jl_gc_num_t gc_num;
240-
extern region_t *regions[REGION_COUNT];
241-
extern int regions_lb[REGION_COUNT];
242-
extern int regions_ub[REGION_COUNT];
246+
extern region_t regions[REGION_COUNT];
243247
extern bigval_t *big_objects_marked;
244248
extern arraylist_t finalizer_list;
245249
extern arraylist_t finalizer_list_marked;
@@ -282,11 +286,11 @@ NOINLINE uintptr_t gc_get_stack_ptr(void);
282286
STATIC_INLINE region_t *find_region(void *ptr, int maybe)
283287
{
284288
// on 64bit systems we could probably use a single region and remove this loop
285-
for (int i = 0; i < REGION_COUNT && regions[i]; i++) {
286-
char *begin = regions[i]->pages->data;
287-
char *end = begin + sizeof(regions[i]->pages);
289+
for (int i = 0; i < REGION_COUNT && regions[i].pages; i++) {
290+
char *begin = regions[i].pages->data;
291+
char *end = begin + sizeof(jl_gc_page_t) * REGION_PG_COUNT;
288292
if ((char*)ptr >= begin && (char*)ptr <= end)
289-
return regions[i];
293+
return &regions[i];
290294
}
291295
(void)maybe;
292296
assert(maybe && "find_region failed");

0 commit comments

Comments
 (0)