Set the pointer alignment (in bits) via a C macro generated by the Makefile.PL
[p5sagit/Devel-Size.git] / Size.xs
diff --git a/Size.xs b/Size.xs
index 8236ca6..1911d2e 100644 (file)
--- a/Size.xs
+++ b/Size.xs
@@ -46,7 +46,6 @@
    without excessive memory needs. The assumption is that your CPU cache
    works :-) (And that we're not going to bust it)  */
 
-#define ALIGN_BITS  ( sizeof(void*) >> 1 )
 #define BYTE_BITS    3
 #define LEAF_BITS   (16 - BYTE_BITS)
 #define LEAF_MASK   0x1FFF
@@ -78,7 +77,7 @@ check_new(struct state *st, const void *const p) {
        (and hence hot in the cache) but we can still deal with any unaligned
        pointers.  */
     const size_t cooked_p
-       = (raw_p >> ALIGN_BITS) | (raw_p << (bits - BYTE_BITS));
+       = (raw_p >> ALIGN_BITS) | (raw_p << (bits - ALIGN_BITS));
     const U8 this_bit = 1 << (cooked_p & 0x7);
     U8 **leaf_p;
     U8 *leaf;
@@ -590,6 +589,13 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing,
       /* an array with 10 slots has AvMax() set to 9 - te 2007-04-22 */
       st->total_size += sizeof(SV *) * (AvMAX(thing) + 1);
       dbg_printf(("total_size: %li AvMAX: %li av_len: $i\n", st->total_size, AvMAX(thing), av_len((AV*)thing)));
+
+      if (recurse >= TOTAL_SIZE_RECURSION) {
+         SSize_t i = AvFILLp(thing) + 1;
+
+         while (i--)
+             sv_size(aTHX_ st, AvARRAY(thing)[i], recurse);
+      }
     }
     /* Add in the bits on the other side of the beginning */
 
@@ -645,7 +651,7 @@ 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);
-    sv_size(aTHX_ st, (SV *)CvPADLIST(thing), recurse);
+    sv_size(aTHX_ st, (SV *)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);
@@ -680,7 +686,7 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing,
     st->total_size += sizeof(XPVFM);
     magic_size(thing, st);
     st->total_size += ((XPVIO *) SvANY(thing))->xpv_len;
-    sv_size(aTHX_ st, (SV *)CvPADLIST(thing), recurse);
+    sv_size(aTHX_ st, (SV *)CvPADLIST(thing), SOME_RECURSION);
     sv_size(aTHX_ st, (SV *)CvOUTSIDE(thing), recurse);
 
     if (st->go_yell && !st->fm_whine) {
@@ -743,6 +749,8 @@ PROTOTYPES: DISABLE
 UV
 size(orig_thing)
      SV *orig_thing
+ALIAS:
+    total_size = TOTAL_SIZE_RECURSION
 CODE:
 {
   SV *thing = orig_thing;
@@ -750,117 +758,13 @@ CODE:
   
   /* If they passed us a reference then dereference it. This is the
      only way we can check the sizes of arrays and hashes */
-#if (PERL_VERSION < 11)
-  if (SvOK(thing) && SvROK(thing)) {
-    thing = SvRV(thing);
-  }
-#else
   if (SvROK(thing)) {
     thing = SvRV(thing);
   }
-#endif
 
-  sv_size(aTHX_ st, thing, NO_RECURSION);
+  sv_size(aTHX_ st, thing, ix);
   RETVAL = st->total_size;
   free_state(st);
 }
 OUTPUT:
   RETVAL
-
-
-UV
-total_size(orig_thing)
-       SV *orig_thing
-CODE:
-{
-  SV *thing = orig_thing;
-  /* Array with things we still need to do */
-  AV *pending_array;
-  IV size = 0;
-  struct state *st = new_state(aTHX);
-
-  /* Size starts at zero */
-  RETVAL = 0;
-
-  pending_array = newAV();
-
-  /* If they passed us a reference then dereference it.
-     This is the only way we can check the sizes of arrays and hashes. */
-  if (SvROK(thing)) {
-      thing = SvRV(thing);
-  } 
-
-  /* Put it on the pending array */
-  av_push(pending_array, thing);
-
-  /* Now just yank things off the end of the array until it's done */
-  while (av_len(pending_array) >= 0) {
-    thing = av_pop(pending_array);
-    /* Process it if we've not seen it */
-    if (sv_size(aTHX_ st, thing, TOTAL_SIZE_RECURSION)) {
-      dbg_printf(("# Found type %i at %p\n", SvTYPE(thing), thing));
-    switch (SvTYPE(thing)) {
-    /* fix for bug #24846 (Does not correctly recurse into references in a PVNV-type scalar) */
-    case SVt_PVNV: TAG;
-      if (SvROK(thing))
-        {
-        av_push(pending_array, SvRV(thing));
-        } 
-      TAG;break;
-#if (PERL_VERSION < 11)
-        case SVt_RV: TAG;
-#else
-        case SVt_IV: TAG;
-#endif
-             dbg_printf(("# Found RV\n"));
-          if (SvROK(thing)) {
-             dbg_printf(("# Found RV\n"));
-             av_push(pending_array, SvRV(thing));
-          }
-          TAG;break;
-
-    case SVt_PVAV: TAG;
-      {
-        AV *tempAV = (AV *)thing;
-        SV **tempSV;
-
-        dbg_printf(("# Found type AV\n"));
-        /* Quick alias to cut down on casting */
-        
-        /* Any elements? */
-        if (av_len(tempAV) != -1) {
-          IV index;
-          /* Run through them all */
-          for (index = 0; index <= av_len(tempAV); index++) {
-        /* Did we get something? */
-        if ((tempSV = av_fetch(tempAV, index, 0))) {
-          /* Was it undef? */
-          if (*tempSV != &PL_sv_undef) {
-            /* Apparently not. Save it for later */
-            av_push(pending_array, *tempSV);
-          }
-        }
-          }
-        }
-      }
-      TAG;break;
-
-    default:
-      TAG;break;
-      }
-    } else {
-    /* check_new() returned false: */
-#ifdef DEVEL_SIZE_DEBUGGING
-       if (SvOK(sv)) printf("# Ignore ref copy 0x%x\n", sv);
-       else printf("# Ignore non-sv 0x%x\n", sv);
-#endif
-    }
-  } /* end while */
-
-  RETVAL = st->total_size;
-  free_state(st);
-  SvREFCNT_dec(pending_array);
-}
-OUTPUT:
-  RETVAL
-