Skip to content

Commit 27faae4

Browse files
committed
Fix missing GC root in table.c
1 parent 0b6cab6 commit 27faae4

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

src/dump.c

+1
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,7 @@ static void jl_reinit_item(ios_t *f, jl_value_t *v, int how) {
17631763
switch (how) {
17641764
case 1: { // rehash ObjectIdDict
17651765
jl_array_t **a = (jl_array_t**)v;
1766+
// Assume *a don't need a write barrier
17661767
jl_idtable_rehash(a, jl_array_len(*a));
17671768
jl_gc_wb(v, *a);
17681769
break;

src/julia_internal.h

+2
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ void jl_gc_signal_wait(void);
258258
void jl_dump_bitcode(char *fname, const char *sysimg_data, size_t sysimg_len);
259259
void jl_dump_objfile(char *fname, int jit_model, const char *sysimg_data, size_t sysimg_len);
260260
int32_t jl_get_llvm_gv(jl_value_t *p);
261+
// the first argument to jl_idtable_rehash is used to return a value
262+
// make sure it is rooted if it is used after the function returns
261263
void jl_idtable_rehash(jl_array_t **pa, size_t newsz);
262264

263265
JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module);

src/table.c

+18-7
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,34 @@ static void **jl_table_lookup_bp(jl_array_t **pa, void *key);
1212

1313
void jl_idtable_rehash(jl_array_t **pa, size_t newsz)
1414
{
15+
// Assume *pa don't need a write barrier
16+
// pa doesn't have to be a GC slot but *pa needs to be rooted
1517
size_t sz = jl_array_len(*pa);
1618
size_t i;
1719
void **ol = (void**)(*pa)->data;
18-
*pa = jl_alloc_cell_1d(newsz);
19-
// we do not check the write barrier here
20-
// because pa always points to a C stack location
21-
// (see eqtable_put)
22-
// it should be changed if this assumption no longer holds
20+
jl_array_t *newa = jl_alloc_cell_1d(newsz);
21+
// keep the original array in the original slot since we need `ol`
22+
// to be valid in the loop below.
23+
JL_GC_PUSH1(&newa);
2324
for(i=0; i < sz; i+=2) {
2425
if (ol[i+1] != NULL) {
25-
(*jl_table_lookup_bp(pa, ol[i])) = ol[i+1];
26-
jl_gc_wb(*pa, ol[i+1]);
26+
(*jl_table_lookup_bp(&newa, ol[i])) = ol[i+1];
27+
jl_gc_wb(newa, ol[i+1]);
2728
// it is however necessary here because allocation
2829
// can (and will) occur in a recursive call inside table_lookup_bp
2930
}
3031
}
32+
*pa = newa;
33+
// we do not check the write barrier here
34+
// because pa always points to a C stack location
35+
// (see jl_eqtable_put and jl_finalize_deserializer)
36+
// it should be changed if this assumption no longer holds
37+
JL_GC_POP();
3138
}
3239

3340
static void **jl_table_lookup_bp(jl_array_t **pa, void *key)
3441
{
42+
// pa points to a **rooted** gc frame slot
3543
uint_t hv;
3644
jl_array_t *a = *pa;
3745
size_t orig, index, iter;
@@ -116,9 +124,12 @@ static void **jl_table_peek_bp(jl_array_t *a, void *key)
116124
JL_DLLEXPORT
117125
jl_array_t *jl_eqtable_put(jl_array_t *h, void *key, void *val)
118126
{
127+
JL_GC_PUSH1(&h);
128+
// &h may be assigned to in jl_idtable_rehash so it need to be rooted
119129
void **bp = jl_table_lookup_bp(&h, key);
120130
*bp = val;
121131
jl_gc_wb(h, val);
132+
JL_GC_POP();
122133
return h;
123134
}
124135

0 commit comments

Comments
 (0)