# 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; } }