This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_entersub(): mortal-copy args earlier
authorDavid Mitchell <davem@iabyn.com>
Sat, 11 Jul 2015 11:43:43 +0000 (12:43 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 08:59:36 +0000 (08:59 +0000)
Move the code earlier which makes a mortal copy of any PADTMP args.
This should make no functional difference, but will shortly allow
us to move the SAVETMPS earlier too (while still coming after the
mortal copying).

pp_hot.c

index dba67bb..05a84d9 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -3497,6 +3497,23 @@ PP(pp_entersub)
        PADLIST * const padlist = CvPADLIST(cv);
         I32 depth;
 
+        /* keep PADTMP args alive throughout the call (we need to do this
+         * because @_ isn't refcounted). Note that we create the mortals
+         * in the caller's tmps frame, so they won't be freed until after
+         * we return from the sub.
+         */
+       if (LIKELY(hasargs)) {
+            SV **svp = MARK;
+            while (svp < SP) {
+                SV *sv = *++svp;
+                if (!sv)
+                    continue;
+                if (SvPADTMP(sv))
+                    *svp = sv = sv_mortalcopy(sv);
+                SvTEMP_off(sv);
+           }
+        }
+
        PUSHBLOCK(cx, CXt_SUB, MARK);
        PUSHSUB(cx);
        cx->blk_sub.retop = PL_op->op_next;
@@ -3530,18 +3547,6 @@ PP(pp_entersub)
 
            Copy(MARK+1,AvARRAY(av),items,SV*);
            AvFILLp(av) = items - 1;
-       
-           MARK = AvARRAY(av);
-           while (items--) {
-               if (*MARK)
-               {
-                   if (SvPADTMP(*MARK)) {
-                       *MARK = sv_mortalcopy(*MARK);
-                    }
-                   SvTEMP_off(*MARK);
-               }
-               MARK++;
-           }
        }
        SAVETMPS;
        if (UNLIKELY((cx->blk_u16 & OPpENTERSUB_LVAL_MASK) == OPpLVAL_INTRO &&