X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=Size.xs;h=2a210e398a5b62339712f323e3e94008c653be65;hb=574d9fd949280e15565bdd31f6d7c6b445e4884f;hp=65bfd7bac6fc27fb0c804ba5f421c4b98786bab9;hpb=302077b611d1694ac2ba74e6cb40dd0b765e4f5a;p=p5sagit%2FDevel-Size.git diff --git a/Size.xs b/Size.xs index 65bfd7b..2a210e3 100644 --- a/Size.xs +++ b/Size.xs @@ -160,7 +160,8 @@ free_state(struct state *st) Safefree(st); } -static void thing_size(pTHX_ const SV *const, struct state *); +static bool sv_size(pTHX_ struct state *, const SV *const, bool recurse); + typedef enum { OPc_NULL, /* 0 */ OPc_BASEOP, /* 1 */ @@ -332,7 +333,7 @@ magic_size(const SV * const thing, struct state *st) { static void check_new_and_strlen(struct state *st, const char *const p) { if(check_new(st, p)) - st->total_size += strlen(p); + st->total_size += 1 + strlen(p); } static void @@ -405,12 +406,14 @@ op_size(pTHX_ const OP * const baseop, struct state *st) regex_size(cPMOPx(baseop)->op_pmregexp, st); #endif TAG;break; - case OPc_SVOP: TAG; - st->total_size += sizeof(struct pmop); - if (check_new(st, cSVOPx(baseop)->op_sv)) { - thing_size(aTHX_ cSVOPx(baseop)->op_sv, st); - } - TAG;break; + case OPc_SVOP: TAG; + st->total_size += sizeof(struct pmop); + if (!(baseop->op_type == OP_AELEMFAST + && baseop->op_flags & OPf_SPECIAL)) { + /* not an OP_PADAV replacement */ + sv_size(aTHX_ st, cSVOPx(baseop)->op_sv, TRUE); + } + TAG;break; case OPc_PADOP: TAG; st->total_size += sizeof(struct padop); TAG;break; @@ -444,12 +447,8 @@ op_size(pTHX_ const OP * const baseop, struct state *st) check_new_and_strlen(st, basecop->cop_file); check_new_and_strlen(st, basecop->cop_stashpv); #else - if (check_new(st, basecop->cop_stash)) { - thing_size(aTHX_ (SV *)basecop->cop_stash, st); - } - if (check_new(st, basecop->cop_filegv)) { - thing_size(aTHX_ (SV *)basecop->cop_filegv, st); - } + sv_size(aTHX_ st, (SV *)basecop->cop_stash, TRUE); + sv_size(aTHX_ st, (SV *)basecop->cop_filegv, TRUE); #endif } @@ -468,10 +467,14 @@ op_size(pTHX_ const OP * const baseop, struct state *st) # define NEW_HEAD_LAYOUT #endif -static void -thing_size(pTHX_ const SV * const orig_thing, struct state *st) { +static bool +sv_size(pTHX_ struct state *const st, const SV * const orig_thing, + const bool recurse) { const SV *thing = orig_thing; + if(!check_new(st, thing)) + return FALSE; + st->total_size += sizeof(SV); switch (SvTYPE(thing)) { @@ -488,6 +491,8 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { st->total_size += sizeof(IV); # endif #endif + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); TAG;break; /* Is it a float? Like the int, it depends on purify */ case SVt_NV: TAG; @@ -503,22 +508,24 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { #ifndef NEW_HEAD_LAYOUT st->total_size += sizeof(XRV); #endif + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); TAG;break; #endif /* How about a plain string? In which case we need to add in how much has been allocated */ case SVt_PV: TAG; st->total_size += sizeof(XPV); - if(SvROK(thing)) - thing_size(aTHX_ SvRV_const(thing), st); + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); else st->total_size += SvLEN(thing); TAG;break; /* A string with an integer part? */ case SVt_PVIV: TAG; st->total_size += sizeof(XPVIV); - if(SvROK(thing)) - thing_size(aTHX_ SvRV_const(thing), st); + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); else st->total_size += SvLEN(thing); if(SvOOK(thing)) { @@ -528,15 +535,15 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { /* A scalar/string/reference with a float part? */ case SVt_PVNV: TAG; st->total_size += sizeof(XPVNV); - if(SvROK(thing)) - thing_size(aTHX_ SvRV_const(thing), st); + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); else st->total_size += SvLEN(thing); TAG;break; case SVt_PVMG: TAG; st->total_size += sizeof(XPVMG); - if(SvROK(thing)) - thing_size(aTHX_ SvRV_const(thing), st); + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); else st->total_size += SvLEN(thing); magic_size(thing, st); @@ -544,8 +551,8 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { #if PERL_VERSION <= 8 case SVt_PVBM: TAG; st->total_size += sizeof(XPVBM); - if(SvROK(thing)) - thing_size(aTHX_ SvRV_const(thing), st); + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); else st->total_size += SvLEN(thing); magic_size(thing, st); @@ -553,8 +560,8 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { #endif case SVt_PVLV: TAG; st->total_size += sizeof(XPVLV); - if(SvROK(thing)) - thing_size(aTHX_ SvRV_const(thing), st); + if(recurse && SvROK(thing)) + sv_size(aTHX_ st, SvRV_const(thing), TRUE); else st->total_size += SvLEN(thing); magic_size(thing, st); @@ -584,11 +591,7 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { Post 5.9.something this is stored in magic, so will be found there, and Perl_av_arylen_p() takes a non-const AV*, hence compilers rightly complain about AvARYLEN() passing thing to it. */ - if (AvARYLEN(thing)) { - if (check_new(st, AvARYLEN(thing))) { - thing_size(aTHX_ AvARYLEN(thing), st); - } - } + sv_size(aTHX_ st, AvARYLEN(thing), TRUE); #endif magic_size(thing, st); TAG;break; @@ -622,26 +625,13 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { magic_size(thing, st); st->total_size += ((XPVIO *) SvANY(thing))->xpv_len; - if (check_new(st, CvSTASH(thing))) { - thing_size(aTHX_ (SV *)CvSTASH(thing), st); - } - if (check_new(st, SvSTASH(thing))) { - thing_size(aTHX_ (SV *)SvSTASH(thing), st); - } - if (check_new(st, CvGV(thing))) { - thing_size(aTHX_ (SV *)CvGV(thing), st); - } - if (check_new(st, CvPADLIST(thing))) { - thing_size(aTHX_ (SV *)CvPADLIST(thing), st); - } - if (check_new(st, CvOUTSIDE(thing))) { - thing_size(aTHX_ (SV *)CvOUTSIDE(thing), st); - } + sv_size(aTHX_ st, (SV *)CvSTASH(thing), TRUE); + sv_size(aTHX_ st, (SV *)SvSTASH(thing), TRUE); + sv_size(aTHX_ st, (SV *)CvGV(thing), TRUE); + sv_size(aTHX_ st, (SV *)CvPADLIST(thing), TRUE); + sv_size(aTHX_ st, (SV *)CvOUTSIDE(thing), TRUE); if (CvISXSUB(thing)) { - SV *sv = cv_const_sv((CV *)thing); - if (sv) { - thing_size(aTHX_ sv, st); - } + sv_size(aTHX_ st, cv_const_sv((CV *)thing), TRUE); } else { op_size(aTHX_ CvSTART(thing), st); op_size(aTHX_ CvROOT(thing), st); @@ -659,28 +649,13 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { /* Is there something hanging off the glob? */ if (GvGP(thing)) { if (check_new(st, GvGP(thing))) { - st->total_size += sizeof(GP); - { - SV *generic_thing; - if ((generic_thing = (SV *)(GvGP(thing)->gp_sv))) { - thing_size(aTHX_ generic_thing, st); - } - if ((generic_thing = (SV *)(GvGP(thing)->gp_form))) { - thing_size(aTHX_ generic_thing, st); - } - if ((generic_thing = (SV *)(GvGP(thing)->gp_av))) { - thing_size(aTHX_ generic_thing, st); - } - if ((generic_thing = (SV *)(GvGP(thing)->gp_hv))) { - thing_size(aTHX_ generic_thing, st); - } - if ((generic_thing = (SV *)(GvGP(thing)->gp_egv))) { - thing_size(aTHX_ generic_thing, st); - } - if ((generic_thing = (SV *)(GvGP(thing)->gp_cv))) { - thing_size(aTHX_ generic_thing, st); - } - } + st->total_size += sizeof(GP); + sv_size(aTHX_ st, (SV *)(GvGP(thing)->gp_sv), TRUE); + sv_size(aTHX_ st, (SV *)(GvGP(thing)->gp_form), TRUE); + sv_size(aTHX_ st, (SV *)(GvGP(thing)->gp_av), TRUE); + sv_size(aTHX_ st, (SV *)(GvGP(thing)->gp_hv), TRUE); + sv_size(aTHX_ st, (SV *)(GvGP(thing)->gp_egv), TRUE); + sv_size(aTHX_ st, (SV *)(GvGP(thing)->gp_cv), TRUE); } } TAG;break; @@ -688,12 +663,8 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { st->total_size += sizeof(XPVFM); magic_size(thing, st); st->total_size += ((XPVIO *) SvANY(thing))->xpv_len; - if (check_new(st, CvPADLIST(thing))) { - thing_size(aTHX_ (SV *)CvPADLIST(thing), st); - } - if (check_new(st, CvOUTSIDE(thing))) { - thing_size(aTHX_ (SV *)CvOUTSIDE(thing), st); - } + sv_size(aTHX_ st, (SV *)CvPADLIST(thing), TRUE); + sv_size(aTHX_ st, (SV *)CvOUTSIDE(thing), TRUE); if (st->go_yell && !st->fm_whine) { carp("Devel::Size: Calculated sizes for FMs are incomplete"); @@ -711,15 +682,9 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { check_new_and_strlen(st, ((XPVIO *) SvANY(thing))->xio_fmt_name); check_new_and_strlen(st, ((XPVIO *) SvANY(thing))->xio_bottom_name); /* Throw the GVs on the list to be walked if they're not-null */ - if (((XPVIO *) SvANY(thing))->xio_top_gv) { - thing_size(aTHX_ (SV *)((XPVIO *) SvANY(thing))->xio_top_gv, st); - } - if (((XPVIO *) SvANY(thing))->xio_bottom_gv) { - thing_size(aTHX_ (SV *)((XPVIO *) SvANY(thing))->xio_bottom_gv, st); - } - if (((XPVIO *) SvANY(thing))->xio_fmt_gv) { - thing_size(aTHX_ (SV *)((XPVIO *) SvANY(thing))->xio_fmt_gv, st); - } + sv_size(aTHX_ st, (SV *)((XPVIO *) SvANY(thing))->xio_top_gv, TRUE); + sv_size(aTHX_ st, (SV *)((XPVIO *) SvANY(thing))->xio_bottom_gv, TRUE); + sv_size(aTHX_ st, (SV *)((XPVIO *) SvANY(thing))->xio_fmt_gv, TRUE); /* Only go trotting through the IO structures if they're really trottable. If USE_PERLIO is defined we can do this. If @@ -732,6 +697,7 @@ thing_size(pTHX_ const SV * const orig_thing, struct state *st) { default: warn("Devel::Size: Unknown variable type: %d encountered\n", SvTYPE(thing) ); } + return TRUE; } static struct state * @@ -747,6 +713,9 @@ new_state(pTHX) if (NULL != (warn_flag = perl_get_sv("Devel::Size::dangle", FALSE))) { st->dangle_whine = SvIV(warn_flag) ? TRUE : FALSE; } + check_new(st, &PL_sv_undef); + check_new(st, &PL_sv_no); + check_new(st, &PL_sv_yes); return st; } @@ -774,7 +743,7 @@ CODE: } #endif - thing_size(aTHX_ thing, st); + sv_size(aTHX_ st, thing, FALSE); RETVAL = st->total_size; free_state(st); } @@ -811,11 +780,8 @@ CODE: while (av_len(pending_array) >= 0) { thing = av_pop(pending_array); /* Process it if we've not seen it */ - if (check_new(st, thing)) { + if (sv_size(aTHX_ st, thing, TRUE)) { dbg_printf(("# Found type %i at %p\n", SvTYPE(thing), thing)); - /* Is it valid? */ - if (thing) { - /* Yes, it is. So let's check the type */ switch (SvTYPE(thing)) { /* fix for bug #24846 (Does not correctly recurse into references in a PVNV-type scalar) */ case SVt_PVNV: TAG; @@ -894,10 +860,7 @@ CODE: TAG;break; default: TAG;break; - } } - - thing_size(aTHX_ thing, st); } else { /* check_new() returned false: */ #ifdef DEVEL_SIZE_DEBUGGING