Skip to content

Commit

Permalink
Fix leaking CStruct repr_data when compute_allocation_strategy throws
Browse files Browse the repository at this point in the history
  • Loading branch information
niner committed Jan 7, 2021
1 parent c2fff2c commit cceaa01
Showing 1 changed file with 32 additions and 23 deletions.
55 changes: 32 additions & 23 deletions src/6model/reprs/CStruct.c
Expand Up @@ -3,6 +3,26 @@
/* This representation's function pointer table. */
static const MVMREPROps CStruct_this_repr;

/* Free representation data. */
static void gc_free_repr_data(MVMThreadContext *tc, MVMSTable *st) {
MVMCStructREPRData *repr_data = (MVMCStructREPRData *)st->REPR_data;

/* May not have survived to composition. */
if (repr_data == NULL)
return;

if (repr_data->name_to_index_mapping) {
MVM_free_null(repr_data->name_to_index_mapping);
MVM_free_null(repr_data->attribute_locations);
MVM_free_null(repr_data->struct_offsets);
MVM_free_null(repr_data->flattened_stables);
MVM_free_null(repr_data->member_types);
MVM_free_null(repr_data->initialize_slots);
}

MVM_free_null(st->REPR_data);
}

/* Locates all of the attributes. Puts them onto a flattened, ordered
* list of attributes (populating the passed flat_list). Also builds
* the index mapping for doing named lookups. Note index is not related
Expand Down Expand Up @@ -138,6 +158,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in

if (info_alloc == 0) {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc, "Class %s has no attributes, which is illegal with the CStruct representation.", MVM_6model_get_stable_debug_name(tc, st));
}

Expand Down Expand Up @@ -166,6 +187,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in

if (num_dimensions > 1) {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"Only one dimensions supported in CStruct attribute");
}
Expand Down Expand Up @@ -217,6 +239,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in
MVMCArrayREPRData *carray_repr_data = (MVMCArrayREPRData *)STABLE(type)->REPR_data;
if (!carray_repr_data) {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct: can't inline a CArray attribute before its type's definition");
}
Expand Down Expand Up @@ -255,6 +278,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in
MVMCStructREPRData *cstruct_repr_data = (MVMCStructREPRData *)STABLE(type)->REPR_data;
if (!cstruct_repr_data) {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct: can't inline a CStruct attribute before its type's definition");
}
Expand All @@ -272,6 +296,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in
MVMCPPStructREPRData *cppstruct_repr_data = (MVMCPPStructREPRData *)STABLE(type)->REPR_data;
if (!cppstruct_repr_data) {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct: can't inline a CPPStruct attribute before its type's definition");
}
Expand All @@ -289,6 +314,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in
MVMCUnionREPRData *cunion_repr_data = (MVMCUnionREPRData *)STABLE(type)->REPR_data;
if (!cunion_repr_data) {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct: can't inline a CUnion attribute before its type's definition");
}
Expand All @@ -305,6 +331,7 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in
}
else {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct representation only handles attributes of type:\n"
" (u)int8, (u)int16, (u)int32, (u)int64, (u)long, (u)longlong, num32, num64, (s)size_t, bool, Str\n"
Expand All @@ -313,13 +340,15 @@ static void compute_allocation_strategy(MVMThreadContext *tc, MVMObject *repr_in
}
else {
MVM_gc_allocate_gen2_default_clear(tc);
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct representation requires the types of all attributes to be specified");
}

if (bits % 8) {
MVM_gc_allocate_gen2_default_clear(tc);
MVM_exception_throw_adhoc(tc,
gc_free_repr_data(tc, st);
MVM_exception_throw_adhoc(tc,
"CStruct only supports native types that are a multiple of 8 bits wide (was passed: %"PRId32")", bits);
}

Expand Down Expand Up @@ -396,12 +425,12 @@ static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
/* Composes the representation. */
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *repr_info) {
/* Compute allocation strategy. */
MVMCStructREPRData *repr_data = MVM_calloc(1, sizeof(MVMCStructREPRData));
MVMObject *attr_info = MVM_repr_at_key_o(tc, repr_info, tc->instance->str_consts.attribute);
MVMCStructREPRData *repr_data = MVM_calloc(1, sizeof(MVMCStructREPRData));
st->REPR_data = repr_data;
MVM_gc_allocate_gen2_default_set(tc);
compute_allocation_strategy(tc, attr_info, repr_data, st);
MVM_gc_allocate_gen2_default_clear(tc);
st->REPR_data = repr_data;
}

/* Initialize a new instance. */
Expand Down Expand Up @@ -737,26 +766,6 @@ static void gc_mark_repr_data(MVMThreadContext *tc, MVMSTable *st, MVMGCWorklist
}
}

/* Free representation data. */
static void gc_free_repr_data(MVMThreadContext *tc, MVMSTable *st) {
MVMCStructREPRData *repr_data = (MVMCStructREPRData *)st->REPR_data;

/* May not have survived to composition. */
if (repr_data == NULL)
return;

if (repr_data->name_to_index_mapping) {
MVM_free(repr_data->name_to_index_mapping);
MVM_free(repr_data->attribute_locations);
MVM_free(repr_data->struct_offsets);
MVM_free(repr_data->flattened_stables);
MVM_free(repr_data->member_types);
MVM_free(repr_data->initialize_slots);
}

MVM_free(st->REPR_data);
}

/* This is called to do any cleanup of resources when an object gets
* embedded inside another one. Never called on a top-level object. */
static void gc_cleanup(MVMThreadContext *tc, MVMSTable *st, void *data) {
Expand Down

0 comments on commit cceaa01

Please sign in to comment.