Skip to content

Commit

Permalink
Make MVMCapture handle non-interned callsites
Browse files Browse the repository at this point in the history
It should quite rarely see these, but when it does, then it makes the
assumption that it owns and should thus manage the memory associated
with them, freeing it when the capture object is GC'd.
  • Loading branch information
jnthn committed Jun 15, 2020
1 parent 1f70bc2 commit 062447a
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/6model/reprs/MVMCapture.c
Expand Up @@ -33,9 +33,8 @@ static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorkli
for (i = 0; i < count; i++)
if (flags[i] & MVM_CALLSITE_ARG_STR || flags[i] & MVM_CALLSITE_ARG_OBJ)
MVM_gc_worklist_add(tc, worklist, &(body->args[i].o));
if (!body->callsite->is_interned) {
MVM_panic(1, "MVMCapture.gc_mark on non-interned callsite NYI");
}
if (!body->callsite->is_interned)
MVM_callsite_mark(tc, body->callsite, worklist);
}

/* Called by the VM in order to free memory associated with this object. */
Expand All @@ -45,9 +44,8 @@ static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
MVM_fixed_size_free(tc, tc->instance->fsa,
capture->body.callsite->flag_count * sizeof(MVMRegister),
capture->body.args);
if (capture->body.callsite && !capture->body.callsite->is_interned) {
MVM_panic(1, "MVMCapture.gc_free on non-interned callsite NYI");
}
if (capture->body.callsite && !capture->body.callsite->is_interned)
MVM_callsite_destroy(capture->body.callsite);
}

static const MVMStorageSpec storage_spec = {
Expand Down Expand Up @@ -104,7 +102,9 @@ static const MVMREPROps MVMCapture_this_repr = {
NULL, /* describe_refs */
};

/* Form a capture object from an argument description. */
/* Form a capture object from an argument description. If the callsite is not an
* interned one, then it will be copied, since an MVMCapture assumes that it
* owns a non-interned callsite. */
MVMObject * MVM_capture_from_args(MVMThreadContext *tc, MVMArgs arg_info) {
/* Put callsite arguments into a flat buffer. */
MVMCallsite *callsite = arg_info.callsite;
Expand All @@ -116,9 +116,9 @@ MVMObject * MVM_capture_from_args(MVMThreadContext *tc, MVMArgs arg_info) {

/* Form capture object. */
MVMObject *capture = MVM_repr_alloc(tc, tc->instance->boot_types.BOOTCapture);
if (!callsite->is_interned)
MVM_panic(1, "MVM_capture_from_args with non-interned callsite NYI");
((MVMCapture *)capture)->body.callsite = callsite;
((MVMCapture *)capture)->body.callsite = callsite->is_interned
? callsite
: MVM_callsite_copy(tc, callsite);
((MVMCapture *)capture)->body.args = args;
return capture;
}
Expand Down
8 changes: 8 additions & 0 deletions src/core/callsite.c
Expand Up @@ -99,6 +99,14 @@ static MVMint32 callsites_equal(MVMThreadContext *tc, MVMCallsite *cs1, MVMCalls
return 1;
}

/* GC marks a callsite (really, just its named args). */
void MVM_callsite_mark(MVMThreadContext *tc, MVMCallsite *cs, MVMGCWorklist *worklist) {
MVMuint32 num_names = cs->flag_count - cs->num_pos;
MVMuint32 i;
for (i = 0; i < num_names; i++)
MVM_gc_worklist_add(tc, worklist, &(cs->arg_names[i]));
}

/* Destroy a callsite, freeing the memory associated with it. */
void MVM_callsite_destroy(MVMCallsite *cs) {
if (cs->flag_count) {
Expand Down
1 change: 1 addition & 0 deletions src/core/callsite.h
Expand Up @@ -102,6 +102,7 @@ MVM_PUBLIC MVMCallsite * MVM_callsite_get_common(MVMThreadContext *tc, MVMCommon
MVMCallsite * MVM_callsite_copy(MVMThreadContext *tc, const MVMCallsite *cs);
MVM_PUBLIC void MVM_callsite_intern(MVMThreadContext *tc, MVMCallsite **cs,
MVMuint32 force, MVMuint32 steal);
void MVM_callsite_mark(MVMThreadContext *tc, MVMCallsite *cs, MVMGCWorklist *worklist);
void MVM_callsite_destroy(MVMCallsite *cs);
void MVM_callsite_cleanup_interns(MVMInstance *instance);

Expand Down

0 comments on commit 062447a

Please sign in to comment.