This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add old_tmpsfloor field to CXt_SUB context frame
authorDavid Mitchell <davem@iabyn.com>
Sat, 11 Jul 2015 13:42:56 +0000 (14:42 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 08:59:36 +0000 (08:59 +0000)
Rather than saving and restoring PL_tmps_floor on subroutine entry/exit
by using SAVETMPS and the save stack, store the old value directly
in the context struct and make PUSHSUB/POPSUB handle the saving and
restoring.

cop.h
pp_ctl.c
pp_hot.c
pp_sort.c

diff --git a/cop.h b/cop.h
index ede8e99..3a643c3 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -556,6 +556,7 @@ struct block_sub {
     AV *       savearray;
     I32                olddepth;
     PAD                *prevcomppad; /* the caller's PL_comppad */
+    SSize_t     old_tmpsfloor; /* also used in CXt_NULL sort block */
 };
 
 
@@ -587,7 +588,9 @@ struct block_format {
        cx->blk_sub.prevcomppad = PL_comppad;                           \
        cx->cx_type |= (hasargs) ? CXp_HASARGS : 0;                     \
        cx->blk_sub.retop = NULL;                                       \
-        SvREFCNT_inc_simple_void_NN(cv);
+        SvREFCNT_inc_simple_void_NN(cv);                                \
+        cx->blk_sub.old_tmpsfloor = PL_tmps_floor;                      \
+        PL_tmps_floor = PL_tmps_ix;
 
 #define PUSHSUB_GET_LVALUE_MASK(func) \
        /* If the context is indeterminate, then only the lvalue */     \
@@ -669,6 +672,7 @@ struct block_format {
         }                                                               \
        sv = MUTABLE_SV(cx->blk_sub.cv);                                \
        LEAVE_SCOPE(PL_scopestack[cx->blk_oldscopesp-1]);               \
+        PL_tmps_floor = cx->blk_sub.old_tmpsfloor;                      \
         PL_comppad = cx->blk_sub.prevcomppad;                           \
         PL_curpad = LIKELY(PL_comppad) ? AvARRAY(PL_comppad) : NULL;    \
         CvDEPTH((const CV*)sv) = olddepth;                              \
@@ -1228,7 +1232,6 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
        PUSHSTACKi(PERLSI_MULTICALL);                                   \
        PUSHBLOCK(cx, (CXt_SUB|CXp_MULTICALL|flags), PL_stack_sp);      \
        PUSHSUB(cx);                                                    \
-        SAVETMPS;                                                       \
         if (!(flags & CXp_SUB_RE_FAKE))                                 \
             CvDEPTH(cv)++;                                             \
        if (CvDEPTH(cv) >= 2) {                                         \
@@ -1270,14 +1273,22 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
        CV * const _nOnclAshIngNamE_ = the_cv;                          \
        CV * const cv = _nOnclAshIngNamE_;                              \
        PADLIST * const padlist = CvPADLIST(cv);                        \
-        PAD * const prevcomppad = cx->blk_sub.prevcomppad;              \
        cx = &cxstack[cxstack_ix];                                      \
        assert(cx->cx_type & CXp_MULTICALL);                            \
        CvDEPTH(multicall_cv) = cx->blk_sub.olddepth;                   \
         LEAVESUB(multicall_cv);                                                \
        cx->cx_type = (CXt_SUB|CXp_MULTICALL|flags);                    \
-       PUSHSUB(cx);                                                    \
-        cx->blk_sub.prevcomppad = prevcomppad ; /* undo PUSHSUB */      \
+        {                                                               \
+            /* save a few things that we don't want PUSHSUB to zap */   \
+            PAD * const prevcomppad = cx->blk_sub.prevcomppad;          \
+            SSize_t old_floor = cx->blk_sub.old_tmpsfloor;              \
+            SSize_t floor = PL_tmps_floor;                              \
+           PUSHSUB(cx);                                                \
+            /* undo the stuff that PUSHSUB zapped */                    \
+            cx->blk_sub.prevcomppad = prevcomppad ;                     \
+            cx->blk_sub.old_tmpsfloor = old_floor;                      \
+            PL_tmps_floor = floor;                                      \
+        }                                                               \
         if (!(flags & CXp_SUB_RE_FAKE))                                 \
             CvDEPTH(cv)++;                                             \
        if (CvDEPTH(cv) >= 2) {                                         \
index 8ae7d39..e9a6c09 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1975,7 +1975,6 @@ PP(pp_dbstate)
        else {
            PUSHBLOCK(cx, CXt_SUB, SP);
            PUSHSUB_DB(cx);
-            SAVETMPS;
            cx->blk_sub.retop = PL_op->op_next;
            CvDEPTH(cv)++;
            if (CvDEPTH(cv) >= 2) {
@@ -2832,7 +2831,6 @@ PP(pp_goto)
            else {
                PADLIST * const padlist = CvPADLIST(cv);
 
-                SAVETMPS;
                 SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
 
                 /* partial unrolled PUSHSUB(): */
index 5f795b5..66aea46 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -3516,7 +3516,6 @@ PP(pp_entersub)
 
        PUSHBLOCK(cx, CXt_SUB, MARK);
        PUSHSUB(cx);
-       SAVETMPS;
 
        cx->blk_sub.retop = PL_op->op_next;
        if (UNLIKELY((depth = ++CvDEPTH(cv)) >= 2)) {
index df4c05f..f4664f9 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1672,7 +1672,6 @@ PP(pp_sort)
            if (!(flags & OPf_SPECIAL)) {
                cx->cx_type = CXt_SUB;
                PUSHSUB(cx);
-                SAVETMPS;
                if (!is_xsub) {
                    PADLIST * const padlist = CvPADLIST(cv);
 
@@ -1692,8 +1691,12 @@ PP(pp_sort)
 
                }
            }
-            else
-                SAVETMPS;
+            else {
+                /* mimic PUSHSUB. Note that we're cheating and using a
+                 * CXt_NULL block as a CXt_SUB block */
+                cx->blk_sub.old_tmpsfloor = PL_tmps_floor;
+                PL_tmps_floor = PL_tmps_ix;
+            }
 
            cx->cx_type |= CXp_MULTICALL;
            
@@ -1710,6 +1713,10 @@ PP(pp_sort)
                POPSUB(cx, sv);
                LEAVESUB(sv);
            }
+            else
+                /* mimic POPSUB */
+                PL_tmps_floor = cx->blk_sub.old_tmpsfloor;
+
            POPBLOCK(cx,PL_curpm);
            PL_stack_sp = newsp;
            POPSTACK;