Skip to content

Commit

Permalink
Avoid possible threading issues with mixins
Browse files Browse the repository at this point in the history
It's possible that one thread is currently accessing an object while another
one mixes a role into it. As in the latter case we may replace the object's
body, the first thread could end up accessing a body that we just freed in the
thread performing the mixin. Better be safe and use the fixed size allocator
to allocate the replaced object body and free a previously existing one at a
safe point.
  • Loading branch information
niner committed Oct 15, 2021
1 parent f7e0d7d commit c7be428
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions src/6model/reprs/P6opaque.c
Expand Up @@ -141,7 +141,9 @@ static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
}

/* If we replaced the object body, free the replacement. */
MVM_free(((MVMP6opaque *)obj)->body.replaced);
void *replaced = ((MVMP6opaque *)obj)->body.replaced;
if (replaced)
MVM_fixed_size_free(tc, tc->instance->fsa, STABLE(obj)->size - sizeof(MVMObject), replaced);
}

/* Marks the representation data in an STable.*/
Expand Down Expand Up @@ -1241,18 +1243,17 @@ static void allocate_replaced_body(MVMThreadContext *tc, MVMObject *obj, MVMSTab

/* Allocate new memory. */
size_t new_size = new_type->size - sizeof(MVMObject);
void *new = MVM_malloc(new_size);
memset((char *)new + (STABLE(obj)->size - sizeof(MVMObject)),
0, new_size - (STABLE(obj)->size - sizeof(MVMObject)));
size_t old_size = STABLE(obj)->size - sizeof(MVMObject);
void *new = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, new_size);

/* Copy existing to new.
* XXX Need more care here, as may have to re-barrier pointers. */
memcpy(new, old, STABLE(obj)->size - sizeof(MVMObject));
memcpy(new, old, old_size);

/* Pointer switch, taking care of existing body issues. */
if (body->replaced) {
body->replaced = new;
MVM_free(old);
MVM_fixed_size_free_at_safepoint(tc, tc->instance->fsa, old_size, old);
}
else {
body->replaced = new;
Expand Down

0 comments on commit c7be428

Please sign in to comment.