diff options
author | Zefram <zefram@fysh.org> | 2017-11-11 04:06:59 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2017-11-11 04:23:37 +0000 |
commit | 4803e7f74216e2e7d916ba267af33207459d1c8b (patch) | |
tree | dbf79928d645093494446ec919540ff6f7290962 /av.c | |
parent | 7b1af8a66568cbb1b215ecb17fa5f19059208f55 (diff) | |
download | perl-4803e7f74216e2e7d916ba267af33207459d1c8b.tar.gz |
store AV iterator as mg_len in more cases
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.
Diffstat (limited to 'av.c')
-rw-r--r-- | av.c | 20 |
1 files changed, 10 insertions, 10 deletions
@@ -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 } /* |