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

Reply via email to