From 89fc0f0179c135481751fe58fde8560232f76a5f Mon Sep 17 00:00:00 2001 From: bbrtj Date: Wed, 10 Dec 2025 20:15:47 +0100 Subject: [PATCH] Refactor Perl_av_fetch: remove goto, reduce the number of branches --- av.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/av.c b/av.c index 0f41f60bfca3..352c1ac03491 100644 --- a/av.c +++ b/av.c @@ -266,9 +266,6 @@ S_adjust_index(pTHX_ AV *av, const MAGIC *mg, SSize_t *keyp) SV** Perl_av_fetch(pTHX_ AV *av, SSize_t key, I32 lval) { - SSize_t neg; - SSize_t size; - PERL_ARGS_ASSERT_AV_FETCH; if (UNLIKELY(SvRMAGICAL(av))) { @@ -291,24 +288,23 @@ Perl_av_fetch(pTHX_ AV *av, SSize_t key, I32 lval) } } - neg = (key < 0); - size = AvFILLp(av) + 1; - key += neg * size; /* handle negative index without using branch */ + /* recalculating key early helps branch prediction */ + SSize_t neg = key < 0; + SSize_t size = AvFILLp(av) + 1; + key += neg * size; /* the cast from SSize_t to Size_t allows both (key < 0) and (key >= size) * to be tested as a single condition */ - if ((Size_t)key >= (Size_t)size) { - if (UNLIKELY(neg)) - return NULL; - goto emptiness; - } - - if (!AvARRAY(av)[key]) { - emptiness: - return lval ? av_store(av,key,newSV_type(SVt_NULL)) : NULL; - } - - return &AvARRAY(av)[key]; + if ((Size_t)key >= (Size_t)size) + /* Only non-negative out of bounds keys are eligible for lvalue + * treatment, so adjust lval by setting value to 0 if the key was + * negative */ + lval *= !neg; + else if (AvARRAY(av)[key]) + return &AvARRAY(av)[key]; + + /* value does not exist in the array */ + return lval ? av_store(av, key, newSV_type(SVt_NULL)) : NULL; } /*