This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_iter(): optimise stack handling
authorDavid Mitchell <davem@iabyn.com>
Sat, 17 Oct 2015 09:53:10 +0000 (10:53 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 09:18:29 +0000 (09:18 +0000)
Make pp_enteriter() do EXTEND(SP,1); then there's no need for pp_iter() to
check for space to push PL_sv_yes/no each time round the loop.

Since the only stack manipulation in pp_iter is now just pushing a boolean
at the end, remove dSP etc and just directly push to PL_stack_sp at the
end.

pp_ctl.c
pp_hot.c

index e453ad7..16891ab 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2235,6 +2235,7 @@ PP(pp_enteriter)
                AvFILL(cx->blk_loop.state_u.ary.ary) + 1 :
                -1;
        }
+        /* EXTEND(SP, 1) not needed in this branch because we just did POPs */
     }
     else { /* iterating over items on the stack */
         cx->cx_type |= CXt_LOOP_LIST;
@@ -2243,6 +2244,9 @@ PP(pp_enteriter)
             (PL_op->op_private & OPpITER_REVERSED)
                 ? cx->blk_oldsp + 1
                 : cx->blk_loop.state_u.stack.basesp;
+        /* pre-extend stack so pp_iter doesn't have to check every time
+         * it pushes yes/no */
+        EXTEND(SP, 1);
     }
 
     RETURN;
index 524adeb..7b53fb9 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2625,12 +2625,11 @@ PP(pp_multideref)
 
 PP(pp_iter)
 {
-    dSP;
     PERL_CONTEXT *cx;
     SV *oldsv;
     SV **itersvp;
+    SV *retsv;
 
-    EXTEND(SP, 1);
     cx = &cxstack[cxstack_ix];
     itersvp = CxITERVAR(cx);
 
@@ -2645,7 +2644,7 @@ PP(pp_iter)
         STRLEN maxlen = 0;
         const char *max = SvPV_const(end, maxlen);
         if (UNLIKELY(SvNIOK(cur) || SvCUR(cur) > maxlen))
-            RETPUSHNO;
+            goto retno;
 
         oldsv = *itersvp;
         if (LIKELY(SvREFCNT(oldsv) == 1 && !SvMAGICAL(oldsv))) {
@@ -2671,7 +2670,7 @@ PP(pp_iter)
     {
         IV cur = cx->blk_loop.state_u.lazyiv.cur;
        if (UNLIKELY(cur > cx->blk_loop.state_u.lazyiv.end))
-           RETPUSHNO;
+           goto retno;
 
         oldsv = *itersvp;
        /* don't risk potential race */
@@ -2711,7 +2710,7 @@ PP(pp_iter)
                         ? ix > cx->blk_oldsp
                         : ix <= cx->blk_loop.state_u.stack.basesp)
         )
-            RETPUSHNO;
+            goto retno;
 
         sv = PL_stack_base[ix];
         av = NULL;
@@ -2726,7 +2725,7 @@ PP(pp_iter)
                         ? ix > AvFILL(av)
                         : ix < 0)
         )
-            RETPUSHNO;
+            goto retno;
 
         if (UNLIKELY(SvMAGICAL(av) || AvREIFY(av))) {
             SV * const * const svp = av_fetch(av, ix, FALSE);
@@ -2771,7 +2770,19 @@ PP(pp_iter)
     default:
        DIE(aTHX_ "panic: pp_iter, type=%u", CxTYPE(cx));
     }
-    RETPUSHYES;
+
+    retsv = &PL_sv_yes;
+    if (0) {
+      retno:
+        retsv = &PL_sv_no;
+    }
+    /* pp_enteriter should have pre-extended the stack */
+    assert(PL_stack_sp < PL_stack_max);
+    *++PL_stack_sp =retsv;
+
+    return PL_op->op_next;
+
+
 }
 
 /*