From 4563a42f535799ab61850028c8353120b62e31dd Mon Sep 17 00:00:00 2001 From: Richard Leach Date: Sat, 12 Jun 2021 01:28:25 +0100 Subject: [PATCH 1/2] pp_unshift: av_store is often unnecessary --- pp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pp.c b/pp.c index f70d832cf273..ac3b1c30a9da 100644 --- a/pp.c +++ b/pp.c @@ -5845,10 +5845,22 @@ PP(pp_unshift) av_unshift(ary, SP - MARK); PL_delaymagic = DM_DELAY; - while (MARK < SP) { - SV * const sv = newSVsv(*++MARK); - (void)av_store(ary, i++, sv); + + if (!SvSMAGICAL(ary)) { + /* av_store is unnecessary, following the earlier av_unshift */ + while (MARK < SP) { + SV * const sv = newSVsv(*++MARK); + assert(!AvREAL(ary) || AvARRAY(ary)[i] == NULL); + AvARRAY(ary)[i] = sv; + i++; + } + } else { + while (MARK < SP) { + SV * const sv = newSVsv(*++MARK); + (void)av_store(ary, i++, sv); + } } + if (PL_delaymagic & DM_ARRAY_ISA) mg_set(MUTABLE_SV(ary)); PL_delaymagic = old_delaymagic; From cc5f70240e847177c9ded2db500cb67d5157a488 Mon Sep 17 00:00:00 2001 From: Richard Leach Date: Sun, 13 Jun 2021 00:07:03 +0100 Subject: [PATCH 2/2] pp_unshift: revise av_store comment, add asserts --- pp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pp.c b/pp.c index ac3b1c30a9da..a4b4482f8c78 100644 --- a/pp.c +++ b/pp.c @@ -5847,10 +5847,18 @@ PP(pp_unshift) PL_delaymagic = DM_DELAY; if (!SvSMAGICAL(ary)) { - /* av_store is unnecessary, following the earlier av_unshift */ + /* The av_unshift above means that many of the checks inside + * av_store are unnecessary. If ary does not have store magic + * then a simple direct assignment is possible here. */ while (MARK < SP) { SV * const sv = newSVsv(*++MARK); - assert(!AvREAL(ary) || AvARRAY(ary)[i] == NULL); + assert( !SvTIED_mg((const SV *)ary, PERL_MAGIC_tied) ); + assert( i >= 0 ); + assert( !SvREADONLY(ary) ); + assert( AvREAL(ary) || !AvREIFY(ary) ); + assert( i <= AvMAX(ary) ); + assert( i <= AvFILLp(ary) ); + assert( !AvREAL(ary) || AvARRAY(ary)[i] == NULL ); AvARRAY(ary)[i] = sv; i++; }