From 2ebf8a2046483a8d79ad2050abd76cc78e70dd3c Mon Sep 17 00:00:00 2001 From: Richard Leach Date: Sat, 12 Jun 2021 01:28:25 +0100 Subject: pp_unshift: av_store is often unnecessary --- pp.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'pp.c') diff --git a/pp.c b/pp.c index 4908cb5892..168b96d4f4 100644 --- a/pp.c +++ b/pp.c @@ -5859,10 +5859,31 @@ 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 (!SvMAGICAL(ary)) { + /* The av_unshift above means that many of the checks inside + * av_store are unnecessary. If ary does not have magic attached + * then a simple direct assignment is possible here. */ + while (MARK < SP) { + SV * const sv = newSVsv(*++MARK); + 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) ); + if (AvREAL(ary)) + SvREFCNT_dec(AvARRAY(ary)[i]); + 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; -- cgit v1.2.1