From eaa5c2d6b000dc65800ce9556fc9c01103860284 Mon Sep 17 00:00:00 2001 From: Gisle Aas Date: Wed, 15 Jul 1998 05:35:25 +0200 Subject: [PATCH] don't copy foreach itervar when no external refs exist Message-ID: Subject: Re: Testcase for 1..n closure change p4raw-id: //depot/perl@1508 --- pp_hot.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/pp_hot.c b/pp_hot.c index c721680..4fe40cc 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -1457,11 +1457,20 @@ PP(pp_iter) STRLEN maxlen; char *max = SvPV((SV*)av, maxlen); if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) { - /* we need a fresh SV every time so that loop body sees a - * completely new SV for closures/references to work as they - * used to */ - SvREFCNT_dec(*cx->blk_loop.itervar); - *cx->blk_loop.itervar = newSVsv(cur); +#ifndef USE_THREADS /* don't risk potential race */ + if (SvREFCNT(*cx->blk_loop.itervar) == 1) { + /* safe to reuse old SV */ + sv_setsv(*cx->blk_loop.itervar, cur); + } + else +#endif + { + /* we need a fresh SV every time so that loop body sees a + * completely new SV for closures/references to work as + * they used to */ + SvREFCNT_dec(*cx->blk_loop.itervar); + *cx->blk_loop.itervar = newSVsv(cur); + } if (strEQ(SvPVX(cur), max)) sv_setiv(cur, 0); /* terminate next time */ else @@ -1474,11 +1483,20 @@ PP(pp_iter) if (cx->blk_loop.iterix > cx->blk_loop.itermax) RETPUSHNO; - /* we need a fresh SV every time so that loop body sees a - * completely new SV for closures/references to work as they - * used to */ - SvREFCNT_dec(*cx->blk_loop.itervar); - *cx->blk_loop.itervar = newSViv(cx->blk_loop.iterix++); +#ifndef USE_THREADS /* don't risk potential race */ + if (SvREFCNT(*cx->blk_loop.itervar) == 1) { + /* safe to reuse old SV */ + sv_setiv(*cx->blk_loop.itervar, cx->blk_loop.iterix++); + } + else +#endif + { + /* we need a fresh SV every time so that loop body sees a + * completely new SV for closures/references to work as they + * used to */ + SvREFCNT_dec(*cx->blk_loop.itervar); + *cx->blk_loop.itervar = newSViv(cx->blk_loop.iterix++); + } RETPUSHYES; } -- 2.7.4