diff options
author | David Mitchell <davem@iabyn.com> | 2015-10-17 10:53:10 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2016-02-03 09:18:29 +0000 |
commit | 8a1f10dd1e1964fa64cd0dff7196cf3f1f503ae1 (patch) | |
tree | 1310af3fdb36a05a49605ae10eaa89119995ee33 /pp_hot.c | |
parent | 93661e56c6b52b1bf34963a3a62b2a766381cccd (diff) | |
download | perl-8a1f10dd1e1964fa64cd0dff7196cf3f1f503ae1.tar.gz |
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.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 25 |
1 files changed, 18 insertions, 7 deletions
@@ -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; + + } /* |