From: Nicholas Clark Date: Thu, 12 May 2011 16:26:28 +0000 (+0100) Subject: Count the size of the "effective names" of a hash. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b3a37f1a32673069275ca60eafabedece4ea75de;p=p5sagit%2FDevel-Size.git Count the size of the "effective names" of a hash. This code is somewhat cheeky, making direct structure accesses. --- diff --git a/CHANGES b/CHANGES index 969b9fa..3915c41 100644 --- a/CHANGES +++ b/CHANGES @@ -4,7 +4,7 @@ Revision history for Perl extension Devel::Size. * Split out HEK size calculation into hek_size(). Add the shared HE overhead. * Handle shared hash key scalars correctly. * GvNAME() is shared from 5.10 onwards. - * Count HvNAME(), the HV "aux" struct, and the mro_meta struct. + * Count HvNAME(), the HV "aux" struct, the mro_meta struct, and ENAMEs. 0.76 2011-05-11 nicholas * Just fix the version number in the line below. diff --git a/Size.xs b/Size.xs index 2d0fc53..1f22cb9 100644 --- a/Size.xs +++ b/Size.xs @@ -745,8 +745,24 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, if (SvOOK(thing)) { /* This direct access is arguably "naughty": */ struct mro_meta *meta = HvAUX(thing)->xhv_mro_meta; +#if PERL_VERSION > 13 || PERL_SUBVERSION > 8 + /* As is this: */ + I32 count = HvAUX(thing)->xhv_name_count; + + if (count) { + HEK **names = HvAUX(thing)->xhv_name_u.xhvnameu_names; + if (count < 0) + count = -count; + while (--count) + hek_size(aTHX_ st, names[count], 1); + } + else +#endif + { + hek_size(aTHX_ st, HvNAME_HEK(thing), 1); + } + st->total_size += sizeof(struct xpvhv_aux); - hek_size(aTHX_ st, HvNAME_HEK(thing), 1); if (meta) { st->total_size += sizeof(struct mro_meta); sv_size(aTHX_ st, (SV *)meta->mro_nextmethod, TOTAL_SIZE_RECURSION);