Skip to content

Commit

Permalink
Fix data race in inlining extop fixup.
Browse files Browse the repository at this point in the history
This switches to use the fixed size allocator for this memory, which
provides a free-at-safepoint function. Previously, the realloc could
lead to a thread reading memory that was freed by the realloc.
  • Loading branch information
jnthn committed Jan 11, 2017
1 parent 1f20dc7 commit 151cb27
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/6model/reprs/MVMCompUnit.c
Expand Up @@ -87,7 +87,10 @@ static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
MVM_free(body->inline_tweak_mutex);
MVM_free(body->coderefs);
MVM_free(body->callsites);
MVM_free(body->extops);
if (body->extops)
MVM_fixed_size_free(tc, tc->instance->fsa,
body->num_extops * sizeof(MVMExtOpRecord),
body->extops);
MVM_free(body->strings);
MVM_free(body->scs);
MVM_free(body->scs_to_resolve);
Expand Down
3 changes: 2 additions & 1 deletion src/core/bytecode.c
Expand Up @@ -313,7 +313,8 @@ static MVMExtOpRecord * deserialize_extop_records(MVMThreadContext *tc, MVMCompU
if (num == 0)
return NULL;

extops = MVM_calloc(num, sizeof *extops);
extops = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa,
num * sizeof(MVMExtOpRecord));

pos = rs->extop_seg;
for (i = 0; i < num; i++) {
Expand Down
15 changes: 9 additions & 6 deletions src/spesh/inline.c
Expand Up @@ -22,12 +22,15 @@ static void demand_extop(MVMThreadContext *tc, MVMCompUnit *target_cu, MVMCompUn
num_extops = source_cu->body.num_extops;
for (i = 0; i < num_extops; i++) {
if (extops[i].info == info) {
MVMuint32 size = (target_cu->body.num_extops + 1) * sizeof(MVMExtOpRecord);
target_cu->body.extops = target_cu->body.extops
? MVM_realloc(target_cu->body.extops, size)
: MVM_malloc(size);
memcpy(&target_cu->body.extops[target_cu->body.num_extops],
&extops[i], sizeof(MVMExtOpRecord));
MVMuint32 orig_size = target_cu->body.num_extops * sizeof(MVMExtOpRecord);
MVMuint32 new_size = (target_cu->body.num_extops + 1) * sizeof(MVMExtOpRecord);
MVMExtOpRecord *new_extops = MVM_fixed_size_alloc(tc,
tc->instance->fsa, new_size);
memcpy(new_extops, target_cu->body.extops, orig_size);
memcpy(&new_extops[target_cu->body.num_extops], &extops[i], sizeof(MVMExtOpRecord));
MVM_fixed_size_free_at_safepoint(tc, tc->instance->fsa, orig_size,
target_cu->body.extops);
target_cu->body.extops = new_extops;
target_cu->body.num_extops++;
uv_mutex_unlock(target_cu->body.inline_tweak_mutex);
return;
Expand Down

0 comments on commit 151cb27

Please sign in to comment.