X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=Size.xs;h=097b1926254e3c0c894e3c6c41ea32a8121eed68;hb=696b99e26563bb5055fbe91a5ad2426f0284c790;hp=d1ae900e7dd4b89a676c0b6b52fadf902c27be6c;hpb=b71309488bc6064635eabcac81bb327bb6a01b93;p=p5sagit%2FDevel-Size.git diff --git a/Size.xs b/Size.xs index d1ae900..097b192 100644 --- a/Size.xs +++ b/Size.xs @@ -312,18 +312,9 @@ cc_opclass(const OP * const o) size */ static void magic_size(pTHX_ const SV * const thing, struct state *st) { - MAGIC *magic_pointer; + MAGIC *magic_pointer = SvMAGIC(thing); - /* Is there any? */ - if (!SvMAGIC(thing)) { - /* No, bail */ - return; - } - - /* Get the base magic pointer */ - magic_pointer = SvMAGIC(thing); - - /* Have we seen the magic pointer? */ + /* Have we seen the magic pointer? (NULL has always been seen before) */ while (check_new(st, magic_pointer)) { st->total_size += sizeof(MAGIC); @@ -333,6 +324,21 @@ magic_size(pTHX_ const SV * const thing, struct state *st) { st->total_size += sizeof(MGVTBL); } sv_size(aTHX_ st, magic_pointer->mg_obj, TOTAL_SIZE_RECURSION); + if (magic_pointer->mg_len == HEf_SVKEY) { + sv_size(aTHX_ st, (SV *)magic_pointer->mg_ptr, TOTAL_SIZE_RECURSION); + } +#if defined(PERL_MAGIC_utf8) && defined (PERL_MAGIC_UTF8_CACHESIZE) + else if (magic_pointer->mg_type == PERL_MAGIC_utf8) { + if (check_new(st, magic_pointer->mg_ptr)) { + st->total_size += PERL_MAGIC_UTF8_CACHESIZE * 2 * sizeof(STRLEN); + } + } +#endif + else if (magic_pointer->mg_len > 0) { + if (check_new(st, magic_pointer->mg_ptr)) { + st->total_size += magic_pointer->mg_len; + } + } /* Get the next in the chain */ magic_pointer = magic_pointer->mg_moremagic; @@ -492,6 +498,10 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, st->total_size += sizeof(SV); + if (SvTYPE(thing) >= SVt_PVMG) { + magic_size(aTHX_ thing, st); + } + switch (SvTYPE(thing)) { /* Is it undef? */ case SVt_NULL: TAG; @@ -561,7 +571,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, sv_size(aTHX_ st, SvRV_const(thing), recurse); else st->total_size += SvLEN(thing); - magic_size(aTHX_ thing, st); TAG;break; #if PERL_VERSION <= 8 case SVt_PVBM: TAG; @@ -570,7 +579,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, sv_size(aTHX_ st, SvRV_const(thing), recurse); else st->total_size += SvLEN(thing); - magic_size(aTHX_ thing, st); TAG;break; #endif case SVt_PVLV: TAG; @@ -579,7 +587,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, sv_size(aTHX_ st, SvRV_const(thing), recurse); else st->total_size += SvLEN(thing); - magic_size(aTHX_ thing, st); TAG;break; /* How much space is dedicated to the array? Not counting the elements in the array, mind, just the array itself */ @@ -615,7 +622,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, complain about AvARYLEN() passing thing to it. */ sv_size(aTHX_ st, AvARYLEN(thing), recurse); #endif - magic_size(aTHX_ thing, st); TAG;break; case SVt_PVHV: TAG; /* First the base struct */ @@ -642,11 +648,9 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, } } } - magic_size(aTHX_ thing, st); TAG;break; case SVt_PVCV: TAG; st->total_size += sizeof(XPVCV); - magic_size(aTHX_ thing, st); st->total_size += ((XPVIO *) SvANY(thing))->xpv_len; sv_size(aTHX_ st, (SV *)CvSTASH(thing), SOME_RECURSION); @@ -663,7 +667,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, TAG;break; case SVt_PVGV: TAG; - magic_size(aTHX_ thing, st); st->total_size += sizeof(XPVGV); if(isGV_with_GP(thing)) { st->total_size += GvNAMELEN(thing); @@ -693,7 +696,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, TAG;break; case SVt_PVFM: TAG; st->total_size += sizeof(XPVFM); - magic_size(aTHX_ thing, st); st->total_size += ((XPVIO *) SvANY(thing))->xpv_len; sv_size(aTHX_ st, (SV *)CvPADLIST(thing), SOME_RECURSION); sv_size(aTHX_ st, (SV *)CvOUTSIDE(thing), recurse); @@ -705,7 +707,6 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, TAG;break; case SVt_PVIO: TAG; st->total_size += sizeof(XPVIO); - magic_size(aTHX_ thing, st); if (check_new(st, (SvPVX_const(thing)))) { st->total_size += ((XPVIO *) SvANY(thing))->xpv_cur; } @@ -732,17 +733,27 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, return TRUE; } +/* Frustratingly, the vtables aren't const in perl.h + gcc is happy enough to have non-const initialisers in a static array. + VC seems not to be. (Is it actually treating the file as C++?) + So do the maximally portable thing, unless we know it's gcc, in which case + we can do the more space efficient version. */ + +#if __GNUC__ void *vtables[] = { #include "vtables.inc" NULL }; +#endif static struct state * new_state(pTHX) { SV *warn_flag; struct state *st; +#if __GNUC__ void **vt_p = vtables; +#endif Newxz(st, 1, struct state); st->go_yell = TRUE; @@ -755,8 +766,12 @@ new_state(pTHX) check_new(st, &PL_sv_undef); check_new(st, &PL_sv_no); check_new(st, &PL_sv_yes); +#if __GNUC__ while(*vt_p) check_new(st, *vt_p++); +#else +#include "vtables.inc" +#endif return st; }