Skip to content

Commit 1aea0e8

Browse files
committed
Port of 03a0247
gc: improve mallocarrays locality (#56801)
1 parent ec3c02a commit 1aea0e8

File tree

6 files changed

+30
-46
lines changed

6 files changed

+30
-46
lines changed

src/gc-debug.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,13 +1100,14 @@ void gc_stats_big_obj(void)
11001100
v = v->next;
11011101
}
11021102

1103-
mallocarray_t *ma = ptls2->heap.mallocarrays;
1104-
while (ma != NULL) {
1105-
if (gc_marked(jl_astaggedvalue(ma->a)->bits.gc)) {
1103+
void **lst = ptls2->gc_tls.heap.mallocarrays.items;
1104+
for (size_t i = 0, l = ptls2->gc_tls.heap.mallocarrays.len; i < l; i++) {
1105+
jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[i] & ~(uintptr_t)1);
1106+
uint8_t bits = jl_astaggedvalue(m)->bits.gc;
1107+
if (gc_marked(bits)) {
11061108
nused++;
1107-
nbytes += jl_genericmemory_nbytes((jl_genericmemory_t*)ma->a);
1109+
nbytes += jl_genericmemory_nbytes(m);
11081110
}
1109-
ma = ma->next;
11101111
}
11111112
}
11121113

src/gc.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,17 +1121,8 @@ static void sweep_big(jl_ptls_t ptls, int sweep_full) JL_NOTSAFEPOINT
11211121

11221122
void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, int isaligned){
11231123
// This is **NOT** a GC safe point.
1124-
mallocarray_t *ma;
1125-
if (ptls->heap.mafreelist == NULL) {
1126-
ma = (mallocarray_t*)malloc_s(sizeof(mallocarray_t));
1127-
}
1128-
else {
1129-
ma = ptls->heap.mafreelist;
1130-
ptls->heap.mafreelist = ma->next;
1131-
}
1132-
ma->a = (jl_value_t*)((uintptr_t)m | !!isaligned);
1133-
ma->next = ptls->heap.mallocarrays;
1134-
ptls->heap.mallocarrays = ma;
1124+
void *a = (void*)((uintptr_t)m | !!isaligned);
1125+
small_arraylist_push(&ptls->heap.mallocarrays, a);
11351126
}
11361127

11371128

@@ -1245,24 +1236,23 @@ static void sweep_malloced_memory(void) JL_NOTSAFEPOINT
12451236
for (int t_i = 0; t_i < gc_n_threads; t_i++) {
12461237
jl_ptls_t ptls2 = gc_all_tls_states[t_i];
12471238
if (ptls2 != NULL) {
1248-
mallocarray_t *ma = ptls2->heap.mallocarrays;
1249-
mallocarray_t **pma = &ptls2->heap.mallocarrays;
1250-
while (ma != NULL) {
1251-
mallocarray_t *nxt = ma->next;
1252-
jl_value_t *a = (jl_value_t*)((uintptr_t)ma->a & ~1);
1253-
int bits = jl_astaggedvalue(a)->bits.gc;
1254-
if (gc_marked(bits)) {
1255-
pma = &ma->next;
1239+
size_t n = 0;
1240+
size_t l = ptls2->heap.mallocarrays.len;
1241+
void **lst = ptls2->heap.mallocarrays.items;
1242+
// filter without preserving order
1243+
while (n < l) {
1244+
jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[n] & ~1);
1245+
if (gc_marked(jl_astaggedvalue(m)->bits.gc)) {
1246+
n++;
12561247
}
12571248
else {
1258-
*pma = nxt;
1259-
int isaligned = (uintptr_t)ma->a & 1;
1260-
jl_gc_free_memory(a, isaligned);
1261-
free(ma);
1249+
int isaligned = (uintptr_t)lst[n] & 1;
1250+
jl_gc_free_memory(m, isaligned);
1251+
l--;
1252+
lst[n] = lst[l];
12621253
}
1263-
gc_time_count_mallocd_memory(bits);
1264-
ma = nxt;
12651254
}
1255+
ptls2->heap.mallocarrays.len = l;
12661256
}
12671257
}
12681258
gc_time_mallocd_memory_end();
@@ -3968,8 +3958,7 @@ void jl_init_thread_heap(jl_ptls_t ptls)
39683958
small_arraylist_new(&heap->live_tasks, 0);
39693959
for (int i = 0; i < JL_N_STACK_POOLS; i++)
39703960
small_arraylist_new(&heap->free_stacks[i], 0);
3971-
heap->mallocarrays = NULL;
3972-
heap->mafreelist = NULL;
3961+
small_arraylist_new(&heap->mallocarrays, 0);
39733962
heap->big_objects = NULL;
39743963
heap->remset = &heap->_remset[0];
39753964
heap->last_remset = &heap->_remset[1];

src/gc.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ JL_EXTENSION typedef struct _bigval_t {
143143

144144
// data structure for tracking malloc'd arrays and genericmemory.
145145

146-
typedef struct _mallocarray_t {
147-
jl_value_t *a;
148-
struct _mallocarray_t *next;
149-
} mallocarray_t;
150-
151146
// pool page metadata
152147
typedef struct _jl_gc_pagemeta_t {
153148
// next metadata structure in per-thread list

src/julia_threads.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ typedef struct {
130130
small_arraylist_t live_tasks;
131131

132132
// variables for tracking malloc'd arrays
133-
struct _mallocarray_t *mallocarrays;
134-
struct _mallocarray_t *mafreelist;
133+
small_arraylist_t mallocarrays;
135134

136135
// variables for tracking big objects
137136
struct _bigval_t *big_objects;

src/mtarraylist.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ extern "C" {
1414
// but there can be any number of observers
1515

1616
typedef struct {
17-
_Atomic(uint32_t) len;
18-
uint32_t max;
17+
_Atomic(size_t) len;
18+
size_t max;
1919
_Atomic(_Atomic(void*)*) items;
2020
_Atomic(void*) _space[SMALL_AL_N_INLINE];
2121
} small_mtarraylist_t;

src/support/arraylist.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
#define AL_N_INLINE 29
77

8-
#define SMALL_AL_N_INLINE 6
8+
#define SMALL_AL_N_INLINE 5
99

1010
#ifdef __cplusplus
1111
extern "C" {
1212
#endif
1313

1414
#include "analyzer_annotations.h"
1515

16-
typedef struct {
16+
typedef struct { // 32 words
1717
size_t len;
1818
size_t max;
1919
void **items;
@@ -27,9 +27,9 @@ void arraylist_push(arraylist_t *a, void *elt) JL_NOTSAFEPOINT;
2727
void *arraylist_pop(arraylist_t *a) JL_NOTSAFEPOINT;
2828
JL_DLLEXPORT void arraylist_grow(arraylist_t *a, size_t n) JL_NOTSAFEPOINT;
2929

30-
typedef struct {
31-
uint32_t len;
32-
uint32_t max;
30+
typedef struct { // 8 words
31+
size_t len;
32+
size_t max;
3333
void **items;
3434
void *_space[SMALL_AL_N_INLINE];
3535
} small_arraylist_t;

0 commit comments

Comments
 (0)