For other-than-gcc, generate calls to check_new(...)
[p5sagit/Devel-Size.git] / Size.xs
diff --git a/Size.xs b/Size.xs
index d1ae900..14be0be 100644 (file)
--- 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;
@@ -732,17 +738,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 +771,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;
 }