X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=Size.xs;h=ada99cc34d8bf8e6c195c7f2b9f790597b259e0d;hb=a8fa215c7b5b72b98f8e6029907087b0ff176594;hp=840a49dcd5dc0e7ca5137fe209422484bbf4eb52;hpb=222a9dfaf1d486205d119d4f9acdf0f78f7cb2ee;p=p5sagit%2FDevel-Size.git diff --git a/Size.xs b/Size.xs index 840a49d..ada99cc 100644 --- a/Size.xs +++ b/Size.xs @@ -551,7 +551,9 @@ op_size(pTHX_ const OP * const baseop, struct state *st) #ifdef OA_METHOP case OPc_METHOP: TAG; st->total_size += sizeof(struct methop); - if (baseop->op_type != OP_METHOD) + if (baseop->op_type == OP_METHOD) + op_size(aTHX_ ((UNOP *)baseop)->op_first, st); + else sv_size(aTHX_ st, cMETHOPx_meth(baseop), SOME_RECURSION); #if PERL_VERSION*1000+PERL_SUBVERSION >= 21007 if (baseop->op_type == OP_METHOD_REDIR || baseop->op_type == OP_METHOD_REDIR_SUPER) { @@ -565,6 +567,7 @@ op_size(pTHX_ const OP * const baseop, struct state *st) #ifdef OA_UNOP_AUX case OPc_UNAUXOP: TAG; st->total_size += sizeof(struct unop_aux) + sizeof(UNOP_AUX_item) * (cUNOP_AUXx(baseop)->op_aux[-1].uv+1); + op_size(aTHX_ ((UNOP *)baseop)->op_first, st); if (baseop->op_type == OP_MULTIDEREF) { UNOP_AUX_item *items = cUNOP_AUXx(baseop)->op_aux; UV actions = items->uv; @@ -759,17 +762,48 @@ const U8 body_sizes[SVt_LAST] = { #endif }; -#ifdef PadlistNAMES +#if PERL_VERSION*1000+PERL_SUBVERSION >= 21007 +/* This is, as ever, excessively nosey with the implementation, and hence + fragile. */ +padlist_size(pTHX_ struct state *const st, const PADLIST * const padl, + const int recurse) { + SSize_t i; + const PADNAMELIST *pnl; + + if (!check_new(st, padl)) + return; + st->total_size += sizeof(PADLIST); + + st->total_size += sizeof(PADNAMELIST); + pnl = PadlistNAMES(padl); + st->total_size += pnl->xpadnl_max * sizeof(PADNAME *); + i = PadnamelistMAX(pnl) + 1; + while (--i) { + const PADNAME *const pn = + PadnamelistARRAY(pnl)[i]; + if (!pn || pn == &PL_padname_undef || pn == &PL_padname_const) + continue; + if (!check_new(st, pn)) + continue; + st->total_size += STRUCT_OFFSET(struct padname_with_str, xpadn_str[0]) + + PadnameLEN(pn) + 1; + } + + i = PadlistMAX(padl) + 1; + st->total_size += sizeof(PAD*) * i; + while (--i) + sv_size(aTHX_ st, (SV*)PadlistARRAY(padl)[i], recurse); +} + +#elif defined PadlistNAMES static void padlist_size(pTHX_ struct state *const st, const PADLIST * const padl, const int recurse) { SSize_t i; if (!check_new(st, padl)) return; - /* This relies on PADNAMELIST and PAD being typedefed to AV. If that - ever changes, this code will need an update. */ st->total_size += sizeof(PADLIST); - sv_size(aTHX_ st, (SV*)PadlistNAMES(padl), recurse); + sv_size(aTHX_ st, (SV*)PadlistNAMES(padl), TOTAL_SIZE_RECURSION); i = PadlistMAX(padl) + 1; st->total_size += sizeof(PAD*) * i; while (--i) @@ -908,7 +942,8 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, case SVt_PVFM: TAG; - padlist_size(aTHX_ st, CvPADLIST(thing), SOME_RECURSION); + if (PERL_VERSION*1000+PERL_SUBVERSION < 21006 || !CvISXSUB(thing)) + padlist_size(aTHX_ st, CvPADLIST(thing), SOME_RECURSION); sv_size(aTHX_ st, (SV *)CvOUTSIDE(thing), recurse); if (st->go_yell && !st->fm_whine) { @@ -921,7 +956,8 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing, sv_size(aTHX_ st, (SV *)CvSTASH(thing), SOME_RECURSION); sv_size(aTHX_ st, (SV *)SvSTASH(thing), SOME_RECURSION); sv_size(aTHX_ st, (SV *)CvGV(thing), SOME_RECURSION); - padlist_size(aTHX_ st, CvPADLIST(thing), SOME_RECURSION); + if (PERL_VERSION*1000+PERL_SUBVERSION < 21006 || !CvISXSUB(thing)) + padlist_size(aTHX_ st, CvPADLIST(thing), SOME_RECURSION); sv_size(aTHX_ st, (SV *)CvOUTSIDE(thing), recurse); if (CvISXSUB(thing)) { sv_size(aTHX_ st, cv_const_sv((CV *)thing), recurse);