This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
for loops: don't refcount bump orig var
authorDavid Mitchell <davem@iabyn.com>
Thu, 27 Aug 2015 12:43:49 +0000 (13:43 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 08:59:39 +0000 (08:59 +0000)
In something like

    for $pkg_var (...)

pp_enteriter() bumps the reference count or $pkg_var before making
itersave point to it. POPLOOP later decrements this ref count.

This bump is unnecessary; since we are effectively transferring ownership
(and thus ref count contribution) of the $pkg_var SV from the GvSV slot of
*pkg_var to the itersave slot of the context struct, the overall ref count
of the var should remain unchanged.

So skip the bump and later undo. This should make no functional difference;
it's just more efficient.

cop.h
pp_ctl.c

diff --git a/cop.h b/cop.h
index 5cf5a30..08b52f2 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -839,7 +839,6 @@ struct block_loop {
                 svp = &GvSV((GV*)svp);                                  \
                 cursv = *svp;                                           \
                 *svp = cx->blk_loop.itersave;                           \
-                SvREFCNT_dec_NN(cx->blk_loop.itersave);                 \
             }                                                           \
             else {                                                      \
                 cursv = *svp;                                           \
index 1fc7ac5..ce5861b 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2138,7 +2138,7 @@ PP(pp_enteriter)
     else if (LIKELY(isGV(TOPs))) {             /* symbol table variable */
        GV * const gv = MUTABLE_GV(POPs);
        SV** svp = &GvSV(gv);
-        itersave = SvREFCNT_inc(*svp);
+        itersave = *svp;
        *svp = newSV(0);
        itervar = (void *)gv;
     }