in reply to Re^2: perl5.10 Devel::Size behaviour changed?
in thread perl5.10 Devel::Size behaviour changed?

Reported the addition of magic: rt://49437

  • Comment on Re^3: perl5.10 Devel::Size behaviour changed? (bug report)

Replies are listed 'Best First'.
Re^4: perl5.10 Devel::Size behaviour changed? (bug report)
by BrowserUk (Patriarch) on Sep 04, 2009 at 18:24 UTC

    If it's a bug, it's not attributable to Devel::Size. Any operation that queries the size does the same thing:

    perl -MDevel::Peek -e "my @a; Dump \@a, 1; printf qq[SIZE :%d\n], $#a; + Dump \@a, 1" SV = RV(0x34e158) at 0x34e148 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x276630 SV = PVAV(0x34efb8) at 0x276630 REFCNT = 2 FLAGS = (PADMY) ARRAY = 0x0 FILL = -1 MAX = -1 ARYLEN = 0x0 FLAGS = (REAL) SIZE :-1 SV = RV(0x34e290) at 0x34e280 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x276630 SV = PVAV(0x34efb8) at 0x276630 REFCNT = 2 FLAGS = (PADMY,RMG) MAGIC = 0x27fde8 MG_VIRTUAL = &PL_vtbl_arylen_p MG_TYPE = PERL_MAGIC_arylen_p(@) MG_FLAGS = 0x02 REFCOUNTED MG_OBJ = 0x34e148 SV = PVMG(0x261f18) at 0x34e148 REFCNT = 1 FLAGS = (GMG,SMG,pIOK) IV = -1 NV = 0 PV = 0 MAGIC = 0x27fcf8 MG_VIRTUAL = &PL_vtbl_arylen MG_TYPE = PERL_MAGIC_arylen(#) MG_OBJ = 0x276630 ARRAY = 0x0 FILL = -1 MAX = -1 ARYLEN = 0x34e148 FLAGS = (REAL)

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      The reason a change was made:

      FromNicholas Clark
      reply-toEric Brine,
      perl5 porters <perl5-porters@perl.org>
      toEric Brine
      ccperl5 porters <perl5-porters@perl.org>
      dateFri, Sep 4, 2009 at 2:55 PM
      subjectRe: rvalue $#a adds magic

      On Fri, Sep 04, 2009 at 02:46:26PM -0400, Eric Brine wrote:
      > Before 5.10, $#a didn't add magic to @a

      > Since 5.10.0, it does.

      > Is that intentional?
      > What's the purpose?

      It's storing the value for $#a in the magic. Most arrays don't use $#a, which means that before 5.10 nearly every array consumes 1 pointers-worth of memory just to store NULL.

      I did it in 2005: http://perl5.git.perl.org/perl.git/commitdiff/a3874608cd3b

        Hm. Pre-5.10, every array that didn't use $#array, wasted 1 pointer.

        Post 5.10, every array uses that pointer to point to a 12 or 24-byte block of memory whether it is ever used or not.

        And the very act of attempting to check to see if there is any magic attached, causes there to be magic attached.

        That makes no sense at all to me.

        Now the only way D::S can avoid causing the magic to be attached is to either not bother looking to see if there is any; or to dereference the magic pointer directly...

        A microscopic optimisation attempt that causes a macroscopic [sic] pessimisation. Autovivifying magic just because someone wants to know if there is any is...


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

      Any operation that queries the size does the same thing:

      Not so.
      >perl -MDevel::Peek -le"my @a = qw(a b c); print @a-1; Dump \@a,1" 2 SV = RV(0x238c60) at 0x238c54 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x182a22c SV = PVAV(0x239a4c) at 0x182a22c REFCNT = 2 FLAGS = (PADMY) ARRAY = 0x182521c FILL = 2 MAX = 3 ARYLEN = 0x0 FLAGS = (REAL)

      If it's a bug, it's not attributable to Devel::Size.

      If it's a bug that reading $#a adds magic to @a, then that's not attributable to D::S.

      The bug in D::S is that it should be using the method that doesn't add magic.

        I see you removed the "rvalue" reference...

        Anyway, the code of D::S does this:

        if (AvMAX(thing) != -1) { /* an array with 10 slots has AvMax() set to 9 - te 2007-04-22 * +/ total_size += sizeof(SV *) * (AvMAX(thing) + 1);

        And AvMAX is defined as:

        #define AvMAX(av) ((XPVAV*) SvANY(av))->xav_max

        Ie. It simply gets the value from a struct member.

        It also references AvALLOC & AvARYLEN, but neither of those does anything with magic either:

        #define AvARRAY(av) ((av)->sv_u.svu_array) #define AvALLOC(av) (*((SV***)&((XPVAV*) SvANY(av))->xav_alloc)) #define AvMAX(av) ((XPVAV*) SvANY(av))->xav_max #define AvFILLp(av) ((XPVAV*) SvANY(av))->xav_fill #define AvARYLEN(av) (*Perl_av_arylen_p(aTHX_ MUTABLE_AV(av)))

        The only "method" that touches magic is AvFILL:

        #define AvFILL(av) ((SvRMAGICAL((const SV *) (av))) \ ? mg_size(MUTABLE_SV(av)) : AvFILLp(av))

        And AvFILL doesn't appear anywhere in the D::S source.

        So, I say again, the bug does not lie with D::S.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.