Skip to content

Commit

Permalink
Fix missing GC root in table.c
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed Mar 2, 2016
1 parent 0b6cab6 commit 27faae4
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,7 @@ static void jl_reinit_item(ios_t *f, jl_value_t *v, int how) {
switch (how) {
case 1: { // rehash ObjectIdDict
jl_array_t **a = (jl_array_t**)v;
// Assume *a don't need a write barrier
jl_idtable_rehash(a, jl_array_len(*a));
jl_gc_wb(v, *a);
break;
Expand Down
2 changes: 2 additions & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ void jl_gc_signal_wait(void);
void jl_dump_bitcode(char *fname, const char *sysimg_data, size_t sysimg_len);
void jl_dump_objfile(char *fname, int jit_model, const char *sysimg_data, size_t sysimg_len);
int32_t jl_get_llvm_gv(jl_value_t *p);
// the first argument to jl_idtable_rehash is used to return a value
// make sure it is rooted if it is used after the function returns
void jl_idtable_rehash(jl_array_t **pa, size_t newsz);

JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module);
Expand Down
25 changes: 18 additions & 7 deletions src/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,34 @@ static void **jl_table_lookup_bp(jl_array_t **pa, void *key);

void jl_idtable_rehash(jl_array_t **pa, size_t newsz)
{
// Assume *pa don't need a write barrier
// pa doesn't have to be a GC slot but *pa needs to be rooted
size_t sz = jl_array_len(*pa);
size_t i;
void **ol = (void**)(*pa)->data;
*pa = jl_alloc_cell_1d(newsz);
// we do not check the write barrier here
// because pa always points to a C stack location
// (see eqtable_put)
// it should be changed if this assumption no longer holds
jl_array_t *newa = jl_alloc_cell_1d(newsz);
// keep the original array in the original slot since we need `ol`
// to be valid in the loop below.
JL_GC_PUSH1(&newa);
for(i=0; i < sz; i+=2) {
if (ol[i+1] != NULL) {
(*jl_table_lookup_bp(pa, ol[i])) = ol[i+1];
jl_gc_wb(*pa, ol[i+1]);
(*jl_table_lookup_bp(&newa, ol[i])) = ol[i+1];
jl_gc_wb(newa, ol[i+1]);
// it is however necessary here because allocation
// can (and will) occur in a recursive call inside table_lookup_bp
}
}
*pa = newa;
// we do not check the write barrier here
// because pa always points to a C stack location
// (see jl_eqtable_put and jl_finalize_deserializer)
// it should be changed if this assumption no longer holds
JL_GC_POP();
}

static void **jl_table_lookup_bp(jl_array_t **pa, void *key)
{
// pa points to a **rooted** gc frame slot
uint_t hv;
jl_array_t *a = *pa;
size_t orig, index, iter;
Expand Down Expand Up @@ -116,9 +124,12 @@ static void **jl_table_peek_bp(jl_array_t *a, void *key)
JL_DLLEXPORT
jl_array_t *jl_eqtable_put(jl_array_t *h, void *key, void *val)
{
JL_GC_PUSH1(&h);
// &h may be assigned to in jl_idtable_rehash so it need to be rooted
void **bp = jl_table_lookup_bp(&h, key);
*bp = val;
jl_gc_wb(h, val);
JL_GC_POP();
return h;
}

Expand Down

0 comments on commit 27faae4

Please sign in to comment.