Skip to content

Commit f73192b

Browse files
d-nettoRAI CI (GitHub Action Automation)
authored andcommitted
More scalable pool allocator (JuliaLang#50137)
1 parent 719ba73 commit f73192b

File tree

7 files changed

+362
-558
lines changed

7 files changed

+362
-558
lines changed

src/gc-debug.c

Lines changed: 39 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@ jl_gc_pagemeta_t *jl_gc_page_metadata(void *data)
2727
// the end of the page.
2828
JL_DLLEXPORT jl_taggedvalue_t *jl_gc_find_taggedvalue_pool(char *p, size_t *osize_p)
2929
{
30-
if (!page_metadata(p))
30+
if (!gc_alloc_map_is_set(p))
3131
// Not in the pool
3232
return NULL;
33-
struct jl_gc_metadata_ext info = page_metadata_ext(p);
33+
jl_gc_pagemeta_t *meta = page_metadata(p);
3434
char *page_begin = gc_page_data(p) + GC_PAGE_OFFSET;
3535
// In the page header
3636
if (p < page_begin)
3737
return NULL;
3838
size_t ofs = p - page_begin;
39-
// Check if this is a free page
40-
if (!(info.pagetable0->allocmap[info.pagetable0_i32] & (uint32_t)(1 << info.pagetable0_i)))
41-
return NULL;
42-
int osize = info.meta->osize;
39+
int osize = meta->osize;
4340
// Shouldn't be needed, just in case
4441
if (osize == 0)
4542
return NULL;
@@ -111,44 +108,14 @@ static void gc_clear_mark_page(jl_gc_pagemeta_t *pg, int bits)
111108
}
112109
}
113110

114-
static void gc_clear_mark_pagetable0(pagetable0_t *pagetable0, int bits)
115-
{
116-
for (int pg_i = 0; pg_i < REGION0_PG_COUNT / 32; pg_i++) {
117-
uint32_t line = pagetable0->allocmap[pg_i];
118-
if (line) {
119-
for (int j = 0; j < 32; j++) {
120-
if ((line >> j) & 1) {
121-
gc_clear_mark_page(pagetable0->meta[pg_i * 32 + j], bits);
122-
}
123-
}
124-
}
125-
}
126-
}
127-
128-
static void gc_clear_mark_pagetable1(pagetable1_t *pagetable1, int bits)
129-
{
130-
for (int pg_i = 0; pg_i < REGION1_PG_COUNT / 32; pg_i++) {
131-
uint32_t line = pagetable1->allocmap0[pg_i];
132-
if (line) {
133-
for (int j = 0; j < 32; j++) {
134-
if ((line >> j) & 1) {
135-
gc_clear_mark_pagetable0(pagetable1->meta0[pg_i * 32 + j], bits);
136-
}
137-
}
138-
}
139-
}
140-
}
141-
142-
static void gc_clear_mark_pagetable(int bits)
111+
static void gc_clear_mark_outer(int bits)
143112
{
144-
for (int pg_i = 0; pg_i < (REGION2_PG_COUNT + 31) / 32; pg_i++) {
145-
uint32_t line = memory_map.allocmap1[pg_i];
146-
if (line) {
147-
for (int j = 0; j < 32; j++) {
148-
if ((line >> j) & 1) {
149-
gc_clear_mark_pagetable1(memory_map.meta1[pg_i * 32 + j], bits);
150-
}
151-
}
113+
for (int i = 0; i < gc_n_threads; i++) {
114+
jl_ptls_t ptls2 = gc_all_tls_states[i];
115+
jl_gc_pagemeta_t *pg = ptls2->page_metadata_allocd;
116+
while (pg != NULL) {
117+
gc_clear_mark_page(pg, bits);
118+
pg = pg->next;
152119
}
153120
}
154121
}
@@ -184,7 +151,7 @@ static void clear_mark(int bits)
184151
v = v->next;
185152
}
186153

187-
gc_clear_mark_pagetable(bits);
154+
gc_clear_mark_outer(bits);
188155
}
189156

190157
static void restore(void)
@@ -561,7 +528,6 @@ void gc_scrub_record_task(jl_task_t *t)
561528

562529
JL_NO_ASAN static void gc_scrub_range(char *low, char *high)
563530
{
564-
jl_ptls_t ptls = jl_current_task->ptls;
565531
jl_jmp_buf *old_buf = jl_get_safe_restore();
566532
jl_jmp_buf buf;
567533
if (jl_setjmp(buf, 0)) {
@@ -786,45 +752,37 @@ void gc_final_pause_end(int64_t t0, int64_t tend)
786752

787753
static void gc_stats_pagetable0(pagetable0_t *pagetable0, unsigned *p0)
788754
{
789-
for (int pg_i = 0; pg_i < REGION0_PG_COUNT / 32; pg_i++) {
790-
uint32_t line = pagetable0->allocmap[pg_i] | pagetable0->freemap[pg_i];
791-
if (line) {
792-
for (int j = 0; j < 32; j++) {
793-
if ((line >> j) & 1) {
794-
(*p0)++;
795-
}
796-
}
755+
for (int pg_i = 0; pg_i < REGION0_PG_COUNT; pg_i++) {
756+
uint8_t meta = pagetable0->meta[pg_i];
757+
assert(meta == GC_PAGE_UNMAPPED || meta == GC_PAGE_ALLOCATED ||
758+
meta == GC_PAGE_LAZILY_FREED || meta == GC_PAGE_FREED);
759+
if (meta != GC_PAGE_UNMAPPED) {
760+
(*p0)++;
797761
}
798762
}
799763
}
800764

801765
static void gc_stats_pagetable1(pagetable1_t *pagetable1, unsigned *p1, unsigned *p0)
802766
{
803-
for (int pg_i = 0; pg_i < REGION1_PG_COUNT / 32; pg_i++) {
804-
uint32_t line = pagetable1->allocmap0[pg_i] | pagetable1->freemap0[pg_i];
805-
if (line) {
806-
for (int j = 0; j < 32; j++) {
807-
if ((line >> j) & 1) {
808-
(*p1)++;
809-
gc_stats_pagetable0(pagetable1->meta0[pg_i * 32 + j], p0);
810-
}
811-
}
767+
for (int pg_i = 0; pg_i < REGION1_PG_COUNT; pg_i++) {
768+
pagetable0_t *pagetable0 = pagetable1->meta0[pg_i];
769+
if (pagetable0 == NULL) {
770+
continue;
812771
}
772+
(*p1)++;
773+
gc_stats_pagetable0(pagetable0, p0);
813774
}
814775
}
815776

816777
static void gc_stats_pagetable(unsigned *p2, unsigned *p1, unsigned *p0)
817778
{
818-
for (int pg_i = 0; pg_i < (REGION2_PG_COUNT + 31) / 32; pg_i++) {
819-
uint32_t line = memory_map.allocmap1[pg_i] | memory_map.freemap1[pg_i];
820-
if (line) {
821-
for (int j = 0; j < 32; j++) {
822-
if ((line >> j) & 1) {
823-
(*p2)++;
824-
gc_stats_pagetable1(memory_map.meta1[pg_i * 32 + j], p1, p0);
825-
}
826-
}
779+
for (int pg_i = 0; pg_i < REGION2_PG_COUNT; pg_i++) {
780+
pagetable1_t *pagetable1 = alloc_map.meta1[pg_i];
781+
if (pagetable1 == NULL) {
782+
continue;
827783
}
784+
(*p2)++;
785+
gc_stats_pagetable1(pagetable1, p1, p0);
828786
}
829787
}
830788

@@ -833,7 +791,7 @@ void jl_print_gc_stats(JL_STREAM *s)
833791
#ifdef _OS_LINUX_
834792
malloc_stats();
835793
#endif
836-
double ptime = jl_clock_now() - process_t0;
794+
double ptime = jl_hrtime() - process_t0;
837795
jl_safe_printf("exec time\t%.5f sec\n", ptime);
838796
if (gc_num.pause > 0) {
839797
jl_safe_printf("gc time \t%.5f sec (%2.1f%%) in %d (%d full) collections\n",
@@ -1054,7 +1012,7 @@ void jl_gc_debug_init(void)
10541012
#endif
10551013

10561014
#ifdef GC_FINAL_STATS
1057-
process_t0 = jl_clock_now();
1015+
process_t0 = jl_hrtime();
10581016
#endif
10591017
}
10601018

@@ -1176,7 +1134,7 @@ void gc_stats_big_obj(void)
11761134
static int64_t poolobj_sizes[4];
11771135
static int64_t empty_pages;
11781136

1179-
static void gc_count_pool_page(jl_gc_pagemeta_t *pg)
1137+
static void gc_count_pool_page(jl_gc_pagemeta_t *pg) JL_NOTSAFEPOINT
11801138
{
11811139
int osize = pg->osize;
11821140
char *data = pg->data;
@@ -1195,44 +1153,16 @@ static void gc_count_pool_page(jl_gc_pagemeta_t *pg)
11951153
}
11961154
}
11971155

1198-
static void gc_count_pool_pagetable0(pagetable0_t *pagetable0)
1199-
{
1200-
for (int pg_i = 0; pg_i < REGION0_PG_COUNT / 32; pg_i++) {
1201-
uint32_t line = pagetable0->allocmap[pg_i];
1202-
if (line) {
1203-
for (int j = 0; j < 32; j++) {
1204-
if ((line >> j) & 1) {
1205-
gc_count_pool_page(pagetable0->meta[pg_i * 32 + j]);
1206-
}
1207-
}
1208-
}
1209-
}
1210-
}
1211-
1212-
static void gc_count_pool_pagetable1(pagetable1_t *pagetable1)
1213-
{
1214-
for (int pg_i = 0; pg_i < REGION1_PG_COUNT / 32; pg_i++) {
1215-
uint32_t line = pagetable1->allocmap0[pg_i];
1216-
if (line) {
1217-
for (int j = 0; j < 32; j++) {
1218-
if ((line >> j) & 1) {
1219-
gc_count_pool_pagetable0(pagetable1->meta0[pg_i * 32 + j]);
1220-
}
1221-
}
1222-
}
1223-
}
1224-
}
1225-
12261156
static void gc_count_pool_pagetable(void)
12271157
{
1228-
for (int pg_i = 0; pg_i < (REGION2_PG_COUNT + 31) / 32; pg_i++) {
1229-
uint32_t line = memory_map.allocmap1[pg_i];
1230-
if (line) {
1231-
for (int j = 0; j < 32; j++) {
1232-
if ((line >> j) & 1) {
1233-
gc_count_pool_pagetable1(memory_map.meta1[pg_i * 32 + j]);
1234-
}
1158+
for (int i = 0; i < gc_n_threads; i++) {
1159+
jl_ptls_t ptls2 = gc_all_tls_states[i];
1160+
jl_gc_pagemeta_t *pg = ptls2->page_metadata_allocd;
1161+
while (pg != NULL) {
1162+
if (gc_alloc_map_is_set(pg->data)) {
1163+
gc_count_pool_page(pg);
12351164
}
1165+
pg = pg->next;
12361166
}
12371167
}
12381168
}

0 commit comments

Comments
 (0)