1 #define PERL_NO_GET_CONTEXT
8 /* Not yet in ppport.h */
10 # define CvISXSUB(cv) (CvXSUB(cv) ? TRUE : FALSE)
13 # define SvRV_const(rv) SvRV(rv)
17 /* "structured exception" handling is a Microsoft extension to C and C++.
18 It's *not* C++ exception handling - C++ exception handling can't capture
19 SEGVs and suchlike, whereas this can. There's no known analagous
20 functionality on other platforms. */
22 # define TRY_TO_CATCH_SEGV __try
23 # define CAUGHT_EXCEPTION __except(EXCEPTION EXCEPTION_EXECUTE_HANDLER)
25 # define TRY_TO_CATCH_SEGV if(1)
26 # define CAUGHT_EXCEPTION else
30 # define __attribute__(x)
33 #if 0 && defined(DEBUGGING)
34 #define dbg_printf(x) printf x
39 #define TAG /* printf( "# %s(%d)\n", __FILE__, __LINE__ ) */
42 /* The idea is to have a tree structure to store 1 bit per possible pointer
43 address. The lowest 16 bits are stored in a block of 8092 bytes.
44 The blocks are in a 256-way tree, indexed by the reset of the pointer.
45 This can cope with 32 and 64 bit pointers, and any address space layout,
46 without excessive memory needs. The assumption is that your CPU cache
47 works :-) (And that we're not going to bust it) */
49 #define ALIGN_BITS ( sizeof(void*) >> 1 )
51 #define LEAF_BITS (16 - BYTE_BITS)
52 #define LEAF_MASK 0x1FFF
60 /* My hunch (not measured) is that for most architectures pointers will
61 start with 0 bits, hence the start of this array will be hot, and the
62 end unused. So put the flags next to the hot end. */
67 Checks to see if thing is in the bitstring.
68 Returns true or false, and
69 notes thing in the segmented bitstring.
72 check_new(struct state *st, const void *const p) {
73 unsigned int bits = 8 * sizeof(void*);
74 const size_t raw_p = PTR2nat(p);
75 /* This effectively rotates the value right by the number of low always-0
76 bits in an aligned pointer. The assmption is that most (if not all)
77 pointers are aligned, and these will be in the same chain of nodes
78 (and hence hot in the cache) but we can still deal with any unaligned
81 = (raw_p >> ALIGN_BITS) | (raw_p << (bits - BYTE_BITS));
82 const U8 this_bit = 1 << (cooked_p & 0x7);
86 void **tv_p = (void **) (st->tracking);
88 if (NULL == p) return FALSE;
90 const char c = *(const char *)p;
94 warn( "Devel::Size: Encountered invalid pointer: %p\n", p );
100 /* bits now 24 (32 bit pointers) or 56 (64 bit pointers) */
102 /* First level is always present. */
104 i = (unsigned int)((cooked_p >> bits) & 0xFF);
106 Newxz(tv_p[i], 256, void *);
107 tv_p = (void **)(tv_p[i]);
109 } while (bits > LEAF_BITS + BYTE_BITS);
110 /* bits now 16 always */
111 #if !defined(MULTIPLICITY) || PERL_VERSION > 8 || (PERL_VERSION == 8 && PERL_SUBVERSION > 8)
112 /* 5.8.8 and early have an assert() macro that uses Perl_croak, hence needs
113 a my_perl under multiplicity */
116 leaf_p = (U8 **)tv_p;
117 i = (unsigned int)((cooked_p >> bits) & 0xFF);
119 Newxz(leaf_p[i], 1 << LEAF_BITS, U8);
124 i = (unsigned int)((cooked_p >> BYTE_BITS) & LEAF_MASK);
126 if(leaf[i] & this_bit)
134 free_tracking_at(void **tv, int level)
142 free_tracking_at(tv[i], level);
156 free_state(struct state *st)
158 const int top_level = (sizeof(void *) * 8 - LEAF_BITS - BYTE_BITS) / 8;
159 free_tracking_at((void **)st->tracking, top_level);
163 static void thing_size(pTHX_ const SV *const, struct state *);
180 cc_opclass(const OP * const o)
186 return (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP;
188 if (o->op_type == OP_SASSIGN)
189 return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP);
192 if (o->op_type == OP_GV || o->op_type == OP_GVSV || o->op_type == OP_AELEMFAST)
196 if ((o->op_type == OP_TRANS)) {
200 switch (PL_opargs[o->op_type] & OA_CLASS_MASK) {
225 case OA_PVOP_OR_SVOP: TAG;
227 * Character translations (tr///) are usually a PVOP, keeping a
228 * pointer to a table of shorts used to look up translations.
229 * Under utf8, however, a simple table isn't practical; instead,
230 * the OP is an SVOP, and the SV is a reference to a swash
231 * (i.e., an RV pointing to an HV).
233 return (o->op_private & (OPpTRANS_TO_UTF|OPpTRANS_FROM_UTF))
234 ? OPc_SVOP : OPc_PVOP;
242 case OA_BASEOP_OR_UNOP: TAG;
244 * UNI(OP_foo) in toke.c returns token UNI or FUNC1 depending on
245 * whether parens were seen. perly.y uses OPf_SPECIAL to
246 * signal whether a BASEOP had empty parens or none.
247 * Some other UNOPs are created later, though, so the best
248 * test is OPf_KIDS, which is set in newUNOP.
250 return (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP;
252 case OA_FILESTATOP: TAG;
254 * The file stat OPs are created via UNI(OP_foo) in toke.c but use
255 * the OPf_REF flag to distinguish between OP types instead of the
256 * usual OPf_SPECIAL flag. As usual, if OPf_KIDS is set, then we
257 * return OPc_UNOP so that walkoptree can find our children. If
258 * OPf_KIDS is not set then we check OPf_REF. Without OPf_REF set
259 * (no argument to the operator) it's an OP; with OPf_REF set it's
260 * an SVOP (and op_sv is the GV for the filehandle argument).
262 return ((o->op_flags & OPf_KIDS) ? OPc_UNOP :
264 (o->op_flags & OPf_REF) ? OPc_PADOP : OPc_BASEOP);
266 (o->op_flags & OPf_REF) ? OPc_SVOP : OPc_BASEOP);
268 case OA_LOOPEXOP: TAG;
270 * next, last, redo, dump and goto use OPf_SPECIAL to indicate that a
271 * label was omitted (in which case it's a BASEOP) or else a term was
272 * seen. In this last case, all except goto are definitely PVOP but
273 * goto is either a PVOP (with an ordinary constant label), an UNOP
274 * with OPf_STACKED (with a non-constant non-sub) or an UNOP for
275 * OP_REFGEN (with goto &sub) in which case OPf_STACKED also seems to
278 if (o->op_flags & OPf_STACKED)
280 else if (o->op_flags & OPf_SPECIAL)
285 warn("Devel::Size: Can't determine class of operator %s, assuming BASEOP\n",
286 PL_op_name[o->op_type]);
297 /* Figure out how much magic is attached to the SV and return the
300 magic_size(const SV * const thing, struct state *st) {
301 MAGIC *magic_pointer;
304 if (!SvMAGIC(thing)) {
309 /* Get the base magic pointer */
310 magic_pointer = SvMAGIC(thing);
312 /* Have we seen the magic pointer? */
313 while (check_new(st, magic_pointer)) {
314 st->total_size += sizeof(MAGIC);
317 /* Have we seen the magic vtable? */
318 if (check_new(st, magic_pointer->mg_virtual)) {
319 st->total_size += sizeof(MGVTBL);
322 /* Get the next in the chain */
323 magic_pointer = magic_pointer->mg_moremagic;
326 if (st->dangle_whine)
327 warn( "Devel::Size: Encountered bad magic at: %p\n", magic_pointer );
333 check_new_and_strlen(struct state *st, const char *const p) {
335 st->total_size += strlen(p);
339 regex_size(const REGEXP * const baseregex, struct state *st) {
340 if(!check_new(st, baseregex))
342 st->total_size += sizeof(REGEXP);
343 #if (PERL_VERSION < 11)
344 /* Note the size of the paren offset thing */
345 st->total_size += sizeof(I32) * baseregex->nparens * 2;
346 st->total_size += strlen(baseregex->precomp);
348 st->total_size += sizeof(struct regexp);
349 st->total_size += sizeof(I32) * SvANY(baseregex)->nparens * 2;
350 /*st->total_size += strlen(SvANY(baseregex)->subbeg);*/
352 if (st->go_yell && !st->regex_whine) {
353 carp("Devel::Size: Calculated sizes for compiled regexes are incompatible, and probably always will be");
359 op_size(pTHX_ const OP * const baseop, struct state *st)
363 if(!check_new(st, baseop))
366 op_size(aTHX_ baseop->op_next, st);
368 switch (cc_opclass(baseop)) {
369 case OPc_BASEOP: TAG;
370 st->total_size += sizeof(struct op);
373 st->total_size += sizeof(struct unop);
374 op_size(aTHX_ cUNOPx(baseop)->op_first, st);
377 st->total_size += sizeof(struct binop);
378 op_size(aTHX_ cBINOPx(baseop)->op_first, st);
379 op_size(aTHX_ cBINOPx(baseop)->op_last, st);
382 st->total_size += sizeof(struct logop);
383 op_size(aTHX_ cBINOPx(baseop)->op_first, st);
384 op_size(aTHX_ cLOGOPx(baseop)->op_other, st);
386 case OPc_LISTOP: TAG;
387 st->total_size += sizeof(struct listop);
388 op_size(aTHX_ cLISTOPx(baseop)->op_first, st);
389 op_size(aTHX_ cLISTOPx(baseop)->op_last, st);
392 st->total_size += sizeof(struct pmop);
393 op_size(aTHX_ cPMOPx(baseop)->op_first, st);
394 op_size(aTHX_ cPMOPx(baseop)->op_last, st);
395 #if PERL_VERSION < 9 || (PERL_VERSION == 9 && PERL_SUBVERSION < 5)
396 op_size(aTHX_ cPMOPx(baseop)->op_pmreplroot, st);
397 op_size(aTHX_ cPMOPx(baseop)->op_pmreplstart, st);
398 op_size(aTHX_ (OP *)cPMOPx(baseop)->op_pmnext, st);
400 /* This is defined away in perl 5.8.x, but it is in there for
403 regex_size(PM_GETRE(cPMOPx(baseop)), st);
405 regex_size(cPMOPx(baseop)->op_pmregexp, st);
409 st->total_size += sizeof(struct pmop);
410 if (check_new(st, cSVOPx(baseop)->op_sv)) {
411 thing_size(aTHX_ cSVOPx(baseop)->op_sv, st);
415 st->total_size += sizeof(struct padop);
418 check_new_and_strlen(st, cPVOPx(baseop)->op_pv);
420 st->total_size += sizeof(struct loop);
421 op_size(aTHX_ cLOOPx(baseop)->op_first, st);
422 op_size(aTHX_ cLOOPx(baseop)->op_last, st);
423 op_size(aTHX_ cLOOPx(baseop)->op_redoop, st);
424 op_size(aTHX_ cLOOPx(baseop)->op_nextop, st);
425 op_size(aTHX_ cLOOPx(baseop)->op_lastop, st);
430 basecop = (COP *)baseop;
431 st->total_size += sizeof(struct cop);
433 /* Change 33656 by nicholas@mouse-mill on 2008/04/07 11:29:51
434 Eliminate cop_label from struct cop by storing a label as the first
435 entry in the hints hash. Most statements don't have labels, so this
436 will save memory. Not sure how much.
437 The check below will be incorrect fail on bleadperls
438 before 5.11 @33656, but later than 5.10, producing slightly too
439 small memory sizes on these Perls. */
440 #if (PERL_VERSION < 11)
441 check_new_and_strlen(st, basecop->cop_label);
444 check_new_and_strlen(st, basecop->cop_file);
445 check_new_and_strlen(st, basecop->cop_stashpv);
447 if (check_new(st, basecop->cop_stash)) {
448 thing_size(aTHX_ (SV *)basecop->cop_stash, st);
450 if (check_new(st, basecop->cop_filegv)) {
451 thing_size(aTHX_ (SV *)basecop->cop_filegv, st);
462 if (st->dangle_whine)
463 warn( "Devel::Size: Encountered dangling pointer in opcode at: %p\n", baseop );
467 #if PERL_VERSION > 9 || (PERL_VERSION == 9 && PERL_SUBVERSION > 2)
468 # define NEW_HEAD_LAYOUT
472 thing_size(pTHX_ const SV * const orig_thing, struct state *st) {
473 const SV *thing = orig_thing;
475 st->total_size += sizeof(SV);
477 switch (SvTYPE(thing)) {
481 /* Just a plain integer. This will be differently sized depending
482 on whether purify's been compiled in */
484 #ifndef NEW_HEAD_LAYOUT
486 st->total_size += sizeof(sizeof(XPVIV));
488 st->total_size += sizeof(IV);
492 /* Is it a float? Like the int, it depends on purify */
495 st->total_size += sizeof(sizeof(XPVNV));
497 st->total_size += sizeof(NV);
500 #if (PERL_VERSION < 11)
501 /* Is it a reference? */
503 #ifndef NEW_HEAD_LAYOUT
504 st->total_size += sizeof(XRV);
508 /* How about a plain string? In which case we need to add in how
509 much has been allocated */
511 st->total_size += sizeof(XPV);
513 thing_size(aTHX_ SvRV_const(thing), st);
515 st->total_size += SvLEN(thing);
517 /* A string with an integer part? */
519 st->total_size += sizeof(XPVIV);
521 thing_size(aTHX_ SvRV_const(thing), st);
523 st->total_size += SvLEN(thing);
525 st->total_size += SvIVX(thing);
528 /* A scalar/string/reference with a float part? */
530 st->total_size += sizeof(XPVNV);
532 thing_size(aTHX_ SvRV_const(thing), st);
534 st->total_size += SvLEN(thing);
537 st->total_size += sizeof(XPVMG);
539 thing_size(aTHX_ SvRV_const(thing), st);
541 st->total_size += SvLEN(thing);
542 magic_size(thing, st);
544 #if PERL_VERSION <= 8
546 st->total_size += sizeof(XPVBM);
548 thing_size(aTHX_ SvRV_const(thing), st);
550 st->total_size += SvLEN(thing);
551 magic_size(thing, st);
555 st->total_size += sizeof(XPVLV);
557 thing_size(aTHX_ SvRV_const(thing), st);
559 st->total_size += SvLEN(thing);
560 magic_size(thing, st);
562 /* How much space is dedicated to the array? Not counting the
563 elements in the array, mind, just the array itself */
565 st->total_size += sizeof(XPVAV);
566 /* Is there anything in the array? */
567 if (AvMAX(thing) != -1) {
568 /* an array with 10 slots has AvMax() set to 9 - te 2007-04-22 */
569 st->total_size += sizeof(SV *) * (AvMAX(thing) + 1);
570 dbg_printf(("total_size: %li AvMAX: %li av_len: $i\n", st->total_size, AvMAX(thing), av_len((AV*)thing)));
572 /* Add in the bits on the other side of the beginning */
574 dbg_printf(("total_size %li, sizeof(SV *) %li, AvARRAY(thing) %li, AvALLOC(thing)%li , sizeof(ptr) %li \n",
575 st->total_size, sizeof(SV*), AvARRAY(thing), AvALLOC(thing), sizeof( thing )));
577 /* under Perl 5.8.8 64bit threading, AvARRAY(thing) was a pointer while AvALLOC was 0,
578 resulting in grossly overstated sized for arrays. Technically, this shouldn't happen... */
579 if (AvALLOC(thing) != 0) {
580 st->total_size += (sizeof(SV *) * (AvARRAY(thing) - AvALLOC(thing)));
582 #if (PERL_VERSION < 9)
583 /* Is there something hanging off the arylen element?
584 Post 5.9.something this is stored in magic, so will be found there,
585 and Perl_av_arylen_p() takes a non-const AV*, hence compilers rightly
586 complain about AvARYLEN() passing thing to it. */
587 if (AvARYLEN(thing)) {
588 if (check_new(st, AvARYLEN(thing))) {
589 thing_size(aTHX_ AvARYLEN(thing), st);
593 magic_size(thing, st);
596 /* First the base struct */
597 st->total_size += sizeof(XPVHV);
598 /* Now the array of buckets */
599 st->total_size += (sizeof(HE *) * (HvMAX(thing) + 1));
600 /* Now walk the bucket chain */
601 if (HvARRAY(thing)) {
604 for (cur_bucket = 0; cur_bucket <= HvMAX(thing); cur_bucket++) {
605 cur_entry = *(HvARRAY(thing) + cur_bucket);
607 st->total_size += sizeof(HE);
608 if (cur_entry->hent_hek) {
609 /* Hash keys can be shared. Have we seen this before? */
610 if (check_new(st, cur_entry->hent_hek)) {
611 st->total_size += HEK_BASESIZE + cur_entry->hent_hek->hek_len + 2;
614 cur_entry = cur_entry->hent_next;
618 magic_size(thing, st);
621 st->total_size += sizeof(XPVCV);
622 magic_size(thing, st);
624 st->total_size += ((XPVIO *) SvANY(thing))->xpv_len;
625 if (check_new(st, CvSTASH(thing))) {
626 thing_size(aTHX_ (SV *)CvSTASH(thing), st);
628 if (check_new(st, SvSTASH(thing))) {
629 thing_size(aTHX_ (SV *)SvSTASH(thing), st);
631 if (check_new(st, CvGV(thing))) {
632 thing_size(aTHX_ (SV *)CvGV(thing), st);
634 if (check_new(st, CvPADLIST(thing))) {
635 thing_size(aTHX_ (SV *)CvPADLIST(thing), st);
637 if (check_new(st, CvOUTSIDE(thing))) {
638 thing_size(aTHX_ (SV *)CvOUTSIDE(thing), st);
640 if (CvISXSUB(thing)) {
641 SV *sv = cv_const_sv((CV *)thing);
643 thing_size(aTHX_ sv, st);
646 op_size(aTHX_ CvSTART(thing), st);
647 op_size(aTHX_ CvROOT(thing), st);
652 magic_size(thing, st);
653 st->total_size += sizeof(XPVGV);
654 st->total_size += GvNAMELEN(thing);
656 /* Is there a file? */
657 check_new_and_strlen(st, GvFILE(thing));
659 /* Is there something hanging off the glob? */
661 if (check_new(st, GvGP(thing))) {
662 st->total_size += sizeof(GP);
665 if ((generic_thing = (SV *)(GvGP(thing)->gp_sv))) {
666 thing_size(aTHX_ generic_thing, st);
668 if ((generic_thing = (SV *)(GvGP(thing)->gp_form))) {
669 thing_size(aTHX_ generic_thing, st);
671 if ((generic_thing = (SV *)(GvGP(thing)->gp_av))) {
672 thing_size(aTHX_ generic_thing, st);
674 if ((generic_thing = (SV *)(GvGP(thing)->gp_hv))) {
675 thing_size(aTHX_ generic_thing, st);
677 if ((generic_thing = (SV *)(GvGP(thing)->gp_egv))) {
678 thing_size(aTHX_ generic_thing, st);
680 if ((generic_thing = (SV *)(GvGP(thing)->gp_cv))) {
681 thing_size(aTHX_ generic_thing, st);
688 st->total_size += sizeof(XPVFM);
689 magic_size(thing, st);
690 st->total_size += ((XPVIO *) SvANY(thing))->xpv_len;
691 if (check_new(st, CvPADLIST(thing))) {
692 thing_size(aTHX_ (SV *)CvPADLIST(thing), st);
694 if (check_new(st, CvOUTSIDE(thing))) {
695 thing_size(aTHX_ (SV *)CvOUTSIDE(thing), st);
698 if (st->go_yell && !st->fm_whine) {
699 carp("Devel::Size: Calculated sizes for FMs are incomplete");
704 st->total_size += sizeof(XPVIO);
705 magic_size(thing, st);
706 if (check_new(st, (SvPVX_const(thing)))) {
707 st->total_size += ((XPVIO *) SvANY(thing))->xpv_cur;
709 /* Some embedded char pointers */
710 check_new_and_strlen(st, ((XPVIO *) SvANY(thing))->xio_top_name);
711 check_new_and_strlen(st, ((XPVIO *) SvANY(thing))->xio_fmt_name);
712 check_new_and_strlen(st, ((XPVIO *) SvANY(thing))->xio_bottom_name);
713 /* Throw the GVs on the list to be walked if they're not-null */
714 if (((XPVIO *) SvANY(thing))->xio_top_gv) {
715 thing_size(aTHX_ (SV *)((XPVIO *) SvANY(thing))->xio_top_gv, st);
717 if (((XPVIO *) SvANY(thing))->xio_bottom_gv) {
718 thing_size(aTHX_ (SV *)((XPVIO *) SvANY(thing))->xio_bottom_gv, st);
720 if (((XPVIO *) SvANY(thing))->xio_fmt_gv) {
721 thing_size(aTHX_ (SV *)((XPVIO *) SvANY(thing))->xio_fmt_gv, st);
724 /* Only go trotting through the IO structures if they're really
725 trottable. If USE_PERLIO is defined we can do this. If
726 not... we can't, so we don't even try */
728 /* Dig into xio_ifp and xio_ofp here */
729 warn("Devel::Size: Can't size up perlio layers yet\n");
733 warn("Devel::Size: Unknown variable type: %d encountered\n", SvTYPE(thing) );
737 static struct state *
742 Newxz(st, 1, struct state);
744 if (NULL != (warn_flag = perl_get_sv("Devel::Size::warn", FALSE))) {
745 st->dangle_whine = st->go_yell = SvIV(warn_flag) ? TRUE : FALSE;
747 if (NULL != (warn_flag = perl_get_sv("Devel::Size::dangle", FALSE))) {
748 st->dangle_whine = SvIV(warn_flag) ? TRUE : FALSE;
753 MODULE = Devel::Size PACKAGE = Devel::Size
762 SV *thing = orig_thing;
763 struct state *st = new_state(aTHX);
765 /* If they passed us a reference then dereference it. This is the
766 only way we can check the sizes of arrays and hashes */
767 #if (PERL_VERSION < 11)
768 if (SvOK(thing) && SvROK(thing)) {
777 thing_size(aTHX_ thing, st);
778 RETVAL = st->total_size;
786 total_size(orig_thing)
790 SV *thing = orig_thing;
791 /* Array with things we still need to do */
794 struct state *st = new_state(aTHX);
796 /* Size starts at zero */
799 pending_array = newAV();
801 /* If they passed us a reference then dereference it.
802 This is the only way we can check the sizes of arrays and hashes. */
807 /* Put it on the pending array */
808 av_push(pending_array, thing);
810 /* Now just yank things off the end of the array until it's done */
811 while (av_len(pending_array) >= 0) {
812 thing = av_pop(pending_array);
813 /* Process it if we've not seen it */
814 if (check_new(st, thing)) {
815 dbg_printf(("# Found type %i at %p\n", SvTYPE(thing), thing));
818 /* Yes, it is. So let's check the type */
819 switch (SvTYPE(thing)) {
820 /* fix for bug #24846 (Does not correctly recurse into references in a PVNV-type scalar) */
824 av_push(pending_array, SvRV(thing));
827 #if (PERL_VERSION < 11)
832 dbg_printf(("# Found RV\n"));
834 dbg_printf(("# Found RV\n"));
835 av_push(pending_array, SvRV(thing));
841 AV *tempAV = (AV *)thing;
844 dbg_printf(("# Found type AV\n"));
845 /* Quick alias to cut down on casting */
848 if (av_len(tempAV) != -1) {
850 /* Run through them all */
851 for (index = 0; index <= av_len(tempAV); index++) {
852 /* Did we get something? */
853 if ((tempSV = av_fetch(tempAV, index, 0))) {
855 if (*tempSV != &PL_sv_undef) {
856 /* Apparently not. Save it for later */
857 av_push(pending_array, *tempSV);
866 dbg_printf(("# Found type HV\n"));
867 /* Is there anything in here? */
868 if (hv_iterinit((HV *)thing)) {
870 while ((temp_he = hv_iternext((HV *)thing))) {
871 av_push(pending_array, hv_iterval((HV *)thing, temp_he));
877 dbg_printf(("# Found type GV\n"));
878 /* Run through all the pieces and push the ones with bits */
880 av_push(pending_array, (SV *)GvSV(thing));
883 av_push(pending_array, (SV *)GvFORM(thing));
886 av_push(pending_array, (SV *)GvAV(thing));
889 av_push(pending_array, (SV *)GvHV(thing));
892 av_push(pending_array, (SV *)GvCV(thing));
900 thing_size(aTHX_ thing, st);
902 /* check_new() returned false: */
903 #ifdef DEVEL_SIZE_DEBUGGING
904 if (SvOK(sv)) printf("# Ignore ref copy 0x%x\n", sv);
905 else printf("# Ignore non-sv 0x%x\n", sv);
910 RETVAL = st->total_size;
912 SvREFCNT_dec(pending_array);