This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
store AV iterator as mg_len in more cases
authorZefram <zefram@fysh.org>
Sat, 11 Nov 2017 04:06:59 +0000 (04:06 +0000)
committerZefram <zefram@fysh.org>
Sat, 11 Nov 2017 04:23:37 +0000 (04:23 +0000)
The iterator of an AV is an IV value attached to the AV via magic.
It may be stored in the space used by mg_len, or it may be stored in
separately allocated space referenced by mg_ptr.  The former is more
efficient, so should be preferred.  The original code for AV iterators
would use mg_len if IV was (the same size as) I32, because mg_len was of
type I32.  Since then mg_len has been increased to type SSize_t, but the
conditional about how AV iterators are stored wasn't updated to match.
As a result, on the now very common 64-bit builds we were missing out on
the opportunity to use the more efficient form of storage.  This commit
updates the condition about how AV iterators are stored, to take account
of the new type.

In principle AV iterators ought to be of type SSize_t, and thus *always*
storable as mg_len.  But Perl_av_iter_p() is in the public API with
its IV* return type, so there is a compatibility issue to address in
changing that.

av.c
mg.c

diff --git a/av.c b/av.c
index cf3386c..ba97fed 100644 (file)
--- a/av.c
+++ b/av.c
@@ -1057,17 +1057,17 @@ Perl_av_iter_p(pTHX_ AV *av) {
     PERL_ARGS_ASSERT_AV_ITER_P;
     assert(SvTYPE(av) == SVt_PVAV);
 
-#if IVSIZE == I32SIZE
-    return (IV *)&(mg->mg_len);
-#else
-    if (!mg->mg_ptr) {
-       IV *temp;
-       mg->mg_len = IVSIZE;
-       Newxz(temp, 1, IV);
-       mg->mg_ptr = (char *) temp;
+    if (sizeof(IV) == sizeof(SSize_t)) {
+       return (IV *)&(mg->mg_len);
+    } else {
+       if (!mg->mg_ptr) {
+           IV *temp;
+           mg->mg_len = IVSIZE;
+           Newxz(temp, 1, IV);
+           mg->mg_ptr = (char *) temp;
+       }
+       return (IV *)mg->mg_ptr;
     }
-    return (IV *)mg->mg_ptr;
-#endif
 }
 
 /*
diff --git a/mg.c b/mg.c
index a133943..a359ebf 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -2184,12 +2184,12 @@ Perl_magic_cleararylen_p(pTHX_ SV *sv, MAGIC *mg)
     PERL_UNUSED_CONTEXT;
 
     /* Reset the iterator when the array is cleared */
-#if IVSIZE == I32SIZE
-    *((IV *) &(mg->mg_len)) = 0;
-#else
-    if (mg->mg_ptr)
-        *((IV *) mg->mg_ptr) = 0;
-#endif
+    if (sizeof(IV) == sizeof(SSize_t)) {
+       *((IV *) &(mg->mg_len)) = 0;
+    } else {
+       if (mg->mg_ptr)
+           *((IV *) mg->mg_ptr) = 0;
+    }
 
     return 0;
 }