From 8a1f10dd1e1964fa64cd0dff7196cf3f1f503ae1 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Sat, 17 Oct 2015 10:53:10 +0100 Subject: [PATCH] pp_iter(): optimise stack handling 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 | 4 ++++ pp_hot.c | 25 ++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/pp_ctl.c b/pp_ctl.c index e453ad7..16891ab 100644 --- 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; diff --git a/pp_hot.c b/pp_hot.c index 524adeb..7b53fb9 100644 --- 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; + + } /* -- 1.8.3.1