PVFMs don't need CvDEPTH, and PVCVs don't use SvIVX, so moving
Nicholas Clark [Mon, 20 Feb 2006 17:48:21 +0000 (17:48 +0000)]
xcv_depth into the IV union saves 4(ish) bytes per CV and format.
"ish" because it was a long, but has been changed to I32 (along with
the corresponding field in struct block_sub) so as not to enlarge the
IV union on platforms where sizeof(long) > sizeof(IV), or struct
block_sub where sizeof(long) > sizeof(I32)

p4raw-id: //depot/perl@27247

cop.h
cv.h
dump.c
ext/B/B/Bytecode.pm
ext/Devel/Peek/t/Peek.t
op.c
sv.c
sv.h

diff --git a/cop.h b/cop.h
index 92a61df..9296464 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -237,7 +237,7 @@ struct block_sub {
     GV *       dfoutgv;
     AV *       savearray;
     AV *       argarray;
-    long       olddepth;
+    I32                olddepth;
     U8         hasargs;
     U8         lval;           /* XXX merge lval and hasargs? */
     PAD                *oldcomppad;
diff --git a/cv.h b/cv.h
index 9e1dce0..224ac2c 100644 (file)
--- a/cv.h
+++ b/cv.h
@@ -15,9 +15,10 @@ struct xpvcv {
     STRLEN     xpv_cur;        /* length of xp_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       IV      xivu_iv;        /* integer value or pv offset */
+       IV      xivu_iv;
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;       /* depth, >= 2 indicates recursive call */
     }          xiv_u;
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
@@ -33,13 +34,13 @@ struct xpvcv {
     }          xcv_root_u;
     GV *       xcv_gv;
     char *     xcv_file;
-    long       xcv_depth;      /* >= 2 indicates recursive call */
+    long       xcv_depth;
     PADLIST *  xcv_padlist;
     CV *       xcv_outside;
-    cv_flags_t xcv_flags;
     U32                xcv_outside_seq; /* the COP sequence (at the point of our
                                  * compilation) in the lexically enclosing
                                  * sub */
+    cv_flags_t xcv_flags;
 };
 
 /*
@@ -71,7 +72,14 @@ Returns the stash of the CV.
 #  define CvFILE_set_from_cop(sv, cop) (CvFILE(sv) = CopFILE(cop))
 #endif
 #define CvFILEGV(sv)   (gv_fetchfile(CvFILE(sv)))
-#define CvDEPTH(sv)    ((XPVCV*)SvANY(sv))->xcv_depth
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define CvDEPTH(sv) (*({const CV *_cv = (CV *)sv; \
+                         assert(SvTYPE(_cv) == SVt_PVCV); \
+                         &((XPVCV*)SvANY(_cv))->xiv_u.xivu_i32; \
+                       }))
+#else
+#  define CvDEPTH(sv)  ((XPVCV*)SvANY(sv))->xiv_u.xivu_i32
+#endif
 #define CvPADLIST(sv)  ((XPVCV*)SvANY(sv))->xcv_padlist
 #define CvOUTSIDE(sv)  ((XPVCV*)SvANY(sv))->xcv_outside
 #define CvFLAGS(sv)    ((XPVCV*)SvANY(sv))->xcv_flags
diff --git a/dump.c b/dump.c
index 15aa750..3779d45 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -1283,8 +1283,8 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        SvREFCNT_dec(d);
        return;
     }
-    if ((type >= SVt_PVIV && type != SVt_PVAV && type != SVt_PVHV)
-       || type == SVt_IV) {
+    if (type == SVt_IV || (type >= SVt_PVIV && type != SVt_PVAV
+                          && type != SVt_PVHV && type != SVt_PVCV)) {
        if (SvIsUV(sv)
 #ifdef PERL_OLD_COPY_ON_WRITE
                       || SvIsCOW(sv)
index 212324c..4497d44 100644 (file)
@@ -7,7 +7,7 @@
 
 package B::Bytecode;
 
-our $VERSION = '1.01';
+our $VERSION = '1.02';
 
 use strict;
 use Config;
@@ -240,6 +240,7 @@ sub B::PVIV::bsave {
        # See note below in B::PVNV::bsave
        return if $sv->isa('B::AV');
        return if $sv->isa('B::HV');
+       return if $sv->isa('B::CV');
     }
     asm "xiv", !ITHREADS && $sv->FLAGS & (SVf_FAKE|SVf_READONLY) ?
        "0 but true" : $sv->IVX;
index dcd3e10..3d5d683 100644 (file)
@@ -218,7 +218,6 @@ do_test(13,
   SV = PVCV\\($ADDR\\) at $ADDR
     REFCNT = 2
     FLAGS = \\(PADMY,POK,pPOK,ANON,WEAKOUTSIDE\\)
-    IV = 0
     NV = 0
     PROTOTYPE = ""
     COMP_STASH = $ADDR\\t"main"
@@ -245,7 +244,6 @@ do_test(14,
   SV = PVCV\\($ADDR\\) at $ADDR
     REFCNT = (3|4)
     FLAGS = \\(\\)
-    IV = 0
     NV = 0
     COMP_STASH = $ADDR\\t"main"
     START = $ADDR ===> \\d+
@@ -491,7 +489,6 @@ do_test(23,
   SV = PVCV\\($ADDR\\) at $ADDR
     REFCNT = (2)
     FLAGS = \\(POK,pPOK,CONST\\)
-    IV = 0
     NV = 0
     PROTOTYPE = ""
     COMP_STASH = 0x0
diff --git a/op.c b/op.c
index 85e8852..591ffa7 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4269,7 +4269,7 @@ Perl_cv_undef(pTHX_ CV *cv)
 #endif
 
     if (!CvISXSUB(cv) && CvROOT(cv)) {
-       if (CvDEPTH(cv))
+       if (SvTYPE(cv) == SVt_PVCV && CvDEPTH(cv))
            Perl_croak(aTHX_ "Can't undef active subroutine");
        ENTER;
 
diff --git a/sv.c b/sv.c
index 7619c7d..4f7f35a 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9819,8 +9819,11 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
                        av_push(param->stashes, dstr);
                }
                break;
-           case SVt_PVFM:
            case SVt_PVCV:
+               if (!(param->flags & CLONEf_COPY_STACKS)) {
+                   CvDEPTH(dstr) = 0;
+               }
+           case SVt_PVFM:
                /* NOTE: not refcounted */
                CvSTASH(dstr)   = hv_dup(CvSTASH(dstr), param);
                OP_REFCNT_LOCK;
@@ -9836,9 +9839,6 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
                 * duped GV may never be freed. A bit of a hack! DAPM */
                CvGV(dstr)      = (param->flags & CLONEf_JOIN_IN) ?
                    NULL : gv_dup(CvGV(dstr), param) ;
-               if (!(param->flags & CLONEf_COPY_STACKS)) {
-                   CvDEPTH(dstr) = 0;
-               }
                PAD_DUP(CvPADLIST(dstr), CvPADLIST(sstr), param);
                CvOUTSIDE(dstr) =
                    CvWEAKOUTSIDE(sstr)
diff --git a/sv.h b/sv.h
index a3f28db..88d3cf8 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -294,6 +294,7 @@ struct xpviv {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
 };
 
@@ -307,6 +308,7 @@ typedef struct {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
 } xpviv_allocated;
 #endif
@@ -334,6 +336,7 @@ struct xpvnv {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
 };
 
@@ -346,6 +349,7 @@ struct xpvmg {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -359,6 +363,7 @@ struct xpvlv {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -385,6 +390,7 @@ struct xpvgv {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -404,6 +410,7 @@ struct xpvbm {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -422,9 +429,10 @@ struct xpvfm {
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       IV      xivu_iv;        /* integer value or pv offset */
+       IV      xivu_iv;        /* PVFMs use the pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -440,13 +448,12 @@ struct xpvfm {
     }          xcv_root_u;
     GV *       xcv_gv;
     char *     xcv_file;
-    long       xcv_depth;      /* >= 2 indicates recursive call */
     AV *       xcv_padlist;
     CV *       xcv_outside;
-    cv_flags_t xcv_flags;
     U32                xcv_outside_seq; /* the COP sequence (at the point of our
                                  * compilation) in the lexically enclosing
                                  * sub */
+    cv_flags_t xcv_flags;
     IV         xfm_lines;
 };
 
@@ -454,9 +461,10 @@ typedef struct {
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       IV      xivu_iv;        /* integer value or pv offset */
+       IV      xivu_iv;        /* PVFMs use the pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -472,13 +480,12 @@ typedef struct {
     }          xcv_root_u;
     GV *       xcv_gv;
     char *     xcv_file;
-    long       xcv_depth;      /* >= 2 indicates recursive call */
     AV *       xcv_padlist;
     CV *       xcv_outside;
-    cv_flags_t xcv_flags;
     U32                xcv_outside_seq; /* the COP sequence (at the point of our
                                  * compilation) in the lexically enclosing
                                  * sub */
+    cv_flags_t xcv_flags;
     IV         xfm_lines;
 } xpvfm_allocated;
 
@@ -490,6 +497,7 @@ struct xpvio {
        IV      xivu_iv;        /* integer value or pv offset */
        UV      xivu_uv;
        void *  xivu_p1;
+       I32     xivu_i32;
     }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
@@ -945,6 +953,7 @@ in gv.h: */
            assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
+           assert(SvTYPE(_svi) != SVt_PVCV);                           \
            &(((XPVIV*) SvANY(_svi))->xiv_iv);                          \
         }))
 #    define SvUVX(sv)                                                  \
@@ -952,6 +961,7 @@ in gv.h: */
            assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
+           assert(SvTYPE(_svi) != SVt_PVCV);                           \
            &(((XPVUV*) SvANY(_svi))->xuv_uv);                          \
         }))
 #    define SvNVX(sv)                                                  \