# New Ticket Created by Bram Geron
# Please include the string: [perl #45695]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=45695 >
Parrot_cont (the internal structure storing info about
(Ret)Continuations) has two fields 'to_ctx' and 'from_ctx'. 'to_ctx'
stores the context that should be active after invoking the
Continuation, but I don't know what 'from_ctx' is supposed to hold (the
context it was made in? the context it was called from?)
To test if 'from_ctx' is redundant, I tried removing the field and all
accesses to it, and no extra tests failed (see patch). I think we can
safely remove the field, if nobody objects.
The patch slightly modifies invalidate_retc_context (which makes sure we
don't get a Continuation that continues to a RetContinuation, that would
be illegal) to explicitly end the loop when we get to the topmost
context. If it wouldn't, Parrot segfaults with from_ctx removed.
include/parrot/sub.h | 2 --
lib/Parrot/Pmc2c/PCCMETHOD.pm | 2 --
src/inter_call.c | 1 -
src/pmc/continuation.pmc | 6 ++----
src/pmc/coroutine.pmc | 1 -
src/pmc/exception_handler.pmc | 1 -
src/pmc/retcontinuation.pmc | 5 -----
src/pmc/sub.pmc | 3 ---
src/sub.c | 12 ++++++------
9 files changed, 8 insertions(+), 25 deletions(-)
Regards,
Bram Geron
diff --git a/include/parrot/sub.h b/include/parrot/sub.h
index 6a1b978..bd6c01e 100644
--- a/include/parrot/sub.h
+++ b/include/parrot/sub.h
@@ -188,8 +188,6 @@ typedef struct Parrot_cont {
opcode_t *address; /* start of bytecode, addr to continue */
struct Parrot_Context *to_ctx; /* pointer to dest context */
struct Stack_Chunk *dynamic_state; /* dest dynamic state */
- /* a Continuation keeps the from_ctx alive */
- struct Parrot_Context *from_ctx; /* sub, this cont is returning from */
opcode_t *current_results; /* ptr into code with get_results opcode
full continuation only */
int runloop_id; /* id of the creating runloop. */
diff --git a/lib/Parrot/Pmc2c/PCCMETHOD.pm b/lib/Parrot/Pmc2c/PCCMETHOD.pm
index 2004d51..f0a900c 100644
--- a/lib/Parrot/Pmc2c/PCCMETHOD.pm
+++ b/lib/Parrot/Pmc2c/PCCMETHOD.pm
@@ -391,7 +391,6 @@ sub rewrite_pccmethod {
}
ctx->current_cont = ret_cont;
- PMC_cont(ret_cont)->from_ctx = ctx;
current_args = interp->current_args;
interp->current_args = NULL;
@@ -558,7 +557,6 @@ END
interp->current_object = $invocant;
interp->current_cont = NEED_CONTINUATION;
ctx->current_cont = ret_cont;
- PMC_cont(ret_cont)->from_ctx = ctx;
pccinvoke_meth = VTABLE_find_method(interp, $invocant, $method_name);
if (PMC_IS_NULL(pccinvoke_meth))
diff --git a/src/inter_call.c b/src/inter_call.c
index f4f66e5..8f2ec02 100644
--- a/src/inter_call.c
+++ b/src/inter_call.c
@@ -1610,7 +1610,6 @@ Parrot_PCCINVOKE(PARROT_INTERP, NULLOK(PMC* pmc),
NOTNULL(STRING *method_name),
interp->current_object = pmc;
interp->current_cont = NEED_CONTINUATION;
ctx->current_cont = ret_cont;
- PMC_cont(ret_cont)->from_ctx = ctx;
ctx->ref_count++;
pccinvoke_meth = VTABLE_find_method(interp, pmc,
method_name);
diff --git a/src/pmc/continuation.pmc b/src/pmc/continuation.pmc
index 4f65a7c..8b5a529 100644
--- a/src/pmc/continuation.pmc
+++ b/src/pmc/continuation.pmc
@@ -105,12 +105,10 @@ Destroys the continuation.
#if CTX_LEAK_DEBUG
if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
fprintf(stderr,
- "[destroy cont %p, to_ctx %p, from_ctx %p]\n",
- (void *)SELF, (void *)cc->to_ctx, (void
*)cc->from_ctx);
+ "[destroy cont %p, to_ctx %p]\n",
+ (void *)SELF, (void *)cc->to_ctx);
}
#endif
- if (cc->from_ctx)
- Parrot_free_context(interp, cc->from_ctx, 0);
mem_sys_free(cc);
PMC_struct_val(SELF) = NULL;
}
diff --git a/src/pmc/coroutine.pmc b/src/pmc/coroutine.pmc
index 4ff46f7..fcdd9fa 100644
--- a/src/pmc/coroutine.pmc
+++ b/src/pmc/coroutine.pmc
@@ -175,7 +175,6 @@ Swaps the "context".
co->ctx = ctx;
co->dynamic_state = interp->dynamic_env;
ctx->caller_ctx = caller_ctx;
- PMC_cont(ccont)->from_ctx = ctx;
ctx->current_sub = SELF;
ctx->current_HLL = co->HLL_id;
ctx->current_namespace = co->namespace_stash;
diff --git a/src/pmc/exception_handler.pmc b/src/pmc/exception_handler.pmc
index 93c0b64..46a21bf 100644
--- a/src/pmc/exception_handler.pmc
+++ b/src/pmc/exception_handler.pmc
@@ -93,7 +93,6 @@ Initializes the exception handler.
/* COMPAT: PMC *p5 = REG_PMC(interp, 5);*/
- PARROT_ASSERT(cc->to_ctx == cc->from_ctx);
results = cc->current_results;
/* clear all results, so that continuation.invoke
diff --git a/src/pmc/retcontinuation.pmc b/src/pmc/retcontinuation.pmc
index f902452..c165082 100644
--- a/src/pmc/retcontinuation.pmc
+++ b/src/pmc/retcontinuation.pmc
@@ -85,12 +85,9 @@ Transfers control to the calling context, and frees the
current context.
opcode_t *invoke(void *in_next) {
Parrot_cont *cc = PMC_cont(SELF);
- Parrot_Context *from_ctx = cc->from_ctx;
PackFile_ByteCode * const seg = cc->seg;
opcode_t *next = SUPER(in_next);
- Parrot_free_context(INTERP, from_ctx, 1);
-
#ifdef NDEBUG
/* the continuation is dead - delete and destroy it */
mem_sys_free(cc);
@@ -106,8 +103,6 @@ Transfers control to the calling context, and frees the
current context.
pool->num_free_objects ++;
}
#else
- cc->from_ctx = NULL;
-
/*
* the to_ctx is marked in Continuation.mark
* NULLify it or turn off the custom_mark bit
diff --git a/src/pmc/sub.pmc b/src/pmc/sub.pmc
index 629785f..8d35b2d 100644
--- a/src/pmc/sub.pmc
+++ b/src/pmc/sub.pmc
@@ -259,9 +259,6 @@ Invokes the subroutine.
real_exception(INTERP, next, E_RuntimeError,
"maximum recursion depth exceeded");
- /* and copy set context variables */
- PMC_cont(ccont)->from_ctx = context;
-
/* set context of the sub */
sub->ctx = context;
diff --git a/src/sub.c b/src/sub.c
index b63939a..b9efdbb 100644
--- a/src/sub.c
+++ b/src/sub.c
@@ -131,7 +131,6 @@ new_continuation(PARROT_INTERP, NULLOK(Parrot_cont *to))
Parrot_Context * const to_ctx = to ? to->to_ctx : CONTEXT(interp->ctx);
cc->to_ctx = to_ctx;
- cc->from_ctx = CONTEXT(interp->ctx);
cc->dynamic_state = NULL;
cc->runloop_id = 0;
CONTEXT(interp->ctx)->ref_count++;
@@ -163,7 +162,6 @@ new_ret_continuation(PARROT_INTERP)
Parrot_cont * const cc = mem_allocate_typed(Parrot_cont);
cc->to_ctx = CONTEXT(interp->ctx);
- cc->from_ctx = NULL; /* filled in during a call */
cc->dynamic_state = NULL;
cc->runloop_id = 0;
cc->seg = interp->code;
@@ -226,21 +224,23 @@ Make true Continuation from all RetContinuations up the
call chain.
void
invalidate_retc_context(PARROT_INTERP, NOTNULL(PMC *cont))
{
- Parrot_Context *ctx = PMC_cont(cont)->from_ctx;
+ Parrot_Context *ctx = PMC_cont(cont)->to_ctx;
Parrot_set_context_threshold(interp, ctx);
while (1) {
/*
* We stop if we encounter a true continuation, because
* if one were created, everything up the chain would have been
- * invalidated earlier.
+ * invalidated earlier. We also stop when we get to the topmost
+ * context, which doesn't have a to_ctx.
*/
- if (cont->vtable != interp->vtables[enum_class_RetContinuation])
+ if (!PMC_cont(cont)->address
+ || cont->vtable != interp->vtables[enum_class_RetContinuation])
break;
cont->vtable = interp->vtables[enum_class_Continuation];
ctx->ref_count++;
cont = ctx->current_cont;
- ctx = PMC_cont(cont)->from_ctx;
+ ctx = PMC_cont(cont)->to_ctx;
}
}