Change the IV to a union.
Nicholas Clark [Sun, 29 May 2005 17:46:39 +0000 (17:46 +0000)]
Revert the NV union back to a plain NV
Transpose the positions of IV and NV (NV is now first)
Don't allocate the NV for PV,PVIV,PVAV and PVHV (last 2 non-allocations
currently disabled by default)

p4raw-id: //depot/perl@24617

av.h
cv.h
hv.h
intrpvar.h
sv.c
sv.h

diff --git a/av.h b/av.h
index f377ea9..f8dffc9 100644 (file)
--- a/av.h
+++ b/av.h
@@ -9,21 +9,17 @@
  */
 
 struct xpvav {
-    IV         this_space;
+    NV         xnv_nv;         /* numeric value, if any */
     SSize_t    xav_fill;       /* Index of last element present */
     SSize_t    xav_max;        /* max index for which array has space */
     union {
-       struct {
-           void *xnv_p1;       /* pointer to beginning of C array of SVs */
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
+    SV*                xav_arylen;
 };
 
 #if !defined(PERL_EXPERIMENTAL_LAYOUT)
@@ -33,24 +29,19 @@ typedef struct {
     SSize_t    xav_fill;       /* Index of last element present */
     SSize_t    xav_max;        /* max index for which array has space */
     union {
-       NV      xnvu_nv;
-       struct {
-           void *xnv_p1;       /* pointer to beginning of C array of SVs */
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
+    SV*                xav_arylen;
 } xpvav_allocated;
 #endif
 
 /* SV**        xav_alloc; */
-#define xav_alloc xnv_u.xnv_s.xnv_p1
+#define xav_alloc xiv_u.xivu_p1
 /* SV* xav_arylen; */
-#define xav_arylen xnv_u.xnv_s.xnv_u2.xnv_p2
 
 /* AVf_REAL is set for all AVs whose xav_array contents are refcounted.
  * Some things like "@_" and the scratchpad list do not set this, to
diff --git a/cv.h b/cv.h
index ba8364b..799f8d4 100644 (file)
--- a/cv.h
+++ b/cv.h
  * in sv.h  */
 
 struct xpvcv {
-    IV         awaiting_redevelopment; /* integer value */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of xp_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
 
diff --git a/hv.h b/hv.h
index c99d479..3898e12 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -42,26 +42,20 @@ struct xpvhv_aux {
 /* hash structure: */
 /* This structure must match the beginning of struct xpvmg in sv.h. */
 struct xpvhv {
-    IV         for_rent;
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xhv_fill;       /* how full xhv_array currently is */
     STRLEN     xhv_max;        /* subscript of last element of xhv_array */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;      /* how many elements in the array */
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
-    /* list of pm's for this package is now stored in symtab magic.  */
+    struct xpvhv_aux *xhv_aux;
 };
 
-#define xhv_aux xnv_u.xnv_s.xnv_p1
-#define xhv_keys xnv_u.xnv_s.xnv_u2.xnv_i2
+#define xhv_keys xiv_u.xivu_iv
 
 #if !defined(PERL_EXPERIMENTAL_LAYOUT)
 typedef struct xpvhv xpvhv_allocated;
@@ -70,17 +64,13 @@ typedef struct {
     STRLEN     xhv_fill;       /* how full xhv_array currently is */
     STRLEN     xhv_max;        /* subscript of last element of xhv_array */
     union {
-       NV      xnvu_nv;        /* numeric value, if any */
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;      /* how many elements in the array */
-           }   xnv_u2;
-       }       xnv_s;
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
+    struct xpvhv_aux *xhv_aux;
 } xpvhv_allocated;
 #endif
 
index ae4850c..85a8a21 100644 (file)
@@ -251,7 +251,7 @@ PERLVAR(Isighandlerp,       Sighandler_t)
 
 PERLVAR(Ixnv_root,     NV *)           /* free xnv list */
 PERLVAR(Ixpv_root,     xpv_allocated *)        /* free xpv list */
-PERLVAR(Ixpviv_root,   XPVIV *)        /* free xpviv list */
+PERLVAR(Ixpviv_root,   xpviv_allocated *)      /* free xpviv list */
 PERLVAR(Ixpvnv_root,   XPVNV *)        /* free xpvnv list */
 PERLVAR(Ixpvcv_root,   XPVCV *)        /* free xpvcv list */
 PERLVAR(Ixpvav_root,   xpvav_allocated *)      /* free xpvav list */
@@ -431,7 +431,7 @@ PERLVARI(Ibeginav_save, AV*, Nullav)        /* save BEGIN{}s when compiling */
 
 PERLVAR(Ixnv_arenaroot,        XPV*)           /* list of allocated xnv areas */
 PERLVAR(Ixpv_arenaroot,        xpv_allocated *)        /* list of allocated xpv areas */
-PERLVAR(Ixpviv_arenaroot,XPVIV*)       /* list of allocated xpviv areas */
+PERLVAR(Ixpviv_arenaroot,xpviv_allocated*)     /* list of allocated xpviv areas */
 PERLVAR(Ixpvnv_arenaroot,XPVNV*)       /* list of allocated xpvnv areas */
 PERLVAR(Ixpvcv_arenaroot,XPVCV*)       /* list of allocated xpvcv areas */
 PERLVAR(Ixpvav_arenaroot,xpvav_allocated*)     /* list of allocated xpvav areas */
diff --git a/sv.c b/sv.c
index c838a6d..e8c47f5 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1173,19 +1173,19 @@ S_more_xpv(pTHX)
 STATIC void
 S_more_xpviv(pTHX)
 {
-    XPVIV* xpviv;
-    XPVIV* xpvivend;
-    New(714, xpviv, PERL_ARENA_SIZE/sizeof(XPVIV), XPVIV);
-    *((XPVIV**)xpviv) = PL_xpviv_arenaroot;
+    xpviv_allocated* xpviv;
+    xpviv_allocated* xpvivend;
+    New(713, xpviv, PERL_ARENA_SIZE/sizeof(xpviv_allocated), xpviv_allocated);
+    *((xpviv_allocated**)xpviv) = PL_xpviv_arenaroot;
     PL_xpviv_arenaroot = xpviv;
 
-    xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(XPVIV) - 1];
+    xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(xpviv_allocated) - 1];
     PL_xpviv_root = ++xpviv;
     while (xpviv < xpvivend) {
-       *((XPVIV**)xpviv) = xpviv + 1;
+       *((xpviv_allocated**)xpviv) = xpviv + 1;
        xpviv++;
     }
-    *((XPVIV**)xpviv) = 0;
+    *((xpviv_allocated**)xpviv) = 0;
 }
 
 /* allocate another arena's worth of struct xpvnv */
@@ -1417,14 +1417,20 @@ S_del_xpv(pTHX_ XPV *p)
 STATIC XPVIV*
 S_new_xpviv(pTHX)
 {
-    XPVIV* xpviv;
+    xpviv_allocated* xpviv;
     LOCK_SV_MUTEX;
     if (!PL_xpviv_root)
        S_more_xpviv(aTHX);
     xpviv = PL_xpviv_root;
-    PL_xpviv_root = *(XPVIV**)xpviv;
+    PL_xpviv_root = *(xpviv_allocated**)xpviv;
     UNLOCK_SV_MUTEX;
-    return xpviv;
+    /* If xpviv_allocated is the same structure as XPVIV then the two OFFSETs
+       sum to zero, and the pointer is unchanged. If the allocated structure
+       is smaller (no initial IV actually allocated) then the net effect is
+       to subtract the size of the IV from the pointer, to return a new pointer
+       as if an initial IV were actually allocated.  */
+    return (XPVIV*)((char*)xpviv - STRUCT_OFFSET(XPVIV, xpv_cur)
+                 + STRUCT_OFFSET(xpviv_allocated, xpv_cur));
 }
 
 /* return a struct xpviv to the free list */
@@ -1432,9 +1438,12 @@ S_new_xpviv(pTHX)
 STATIC void
 S_del_xpviv(pTHX_ XPVIV *p)
 {
+    xpviv_allocated* xpviv
+       = (xpviv_allocated*)((char*)(p) + STRUCT_OFFSET(XPVIV, xpv_cur)
+                          - STRUCT_OFFSET(xpviv_allocated, xpv_cur));
     LOCK_SV_MUTEX;
-    *(XPVIV**)p = PL_xpviv_root;
-    PL_xpviv_root = p;
+    *(xpviv_allocated**)xpviv = PL_xpviv_root;
+    PL_xpviv_root = xpviv;
     UNLOCK_SV_MUTEX;
 }
 
diff --git a/sv.h b/sv.h
index b5f1193..a8dcc5b 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -275,7 +275,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVpav_REIFY    0x80000000      /* can become real */
 
 struct xpv {
-    IV         xpv_dummy;      /* This isn't allocated. */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
 };
@@ -290,68 +290,79 @@ typedef struct {
 #endif
 
 struct xpviv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     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 */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
 };
 
+#if 0
+typedef struct xpviv xpviv_allocated;
+#else
+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 */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
+} xpviv_allocated;
+#endif
+
+#define xiv_iv xiv_u.xivu_iv
+
 struct xpvuv {
-    UV         xuv_uv;         /* unsigned value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
+    union {
+       IV      xuvu_iv;
+       UV      xuvu_uv;        /* unsigned value or pv offset */
+       void *  xuvu_p1;
+    }          xuv_u;
 };
 
+#define xuv_uv xuv_u.xuvu_uv
+
 struct xpvnv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
 };
 
-#define xnv_nv xnv_u.xnvu_nv
-
 /* These structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
 };
 
 struct xpvlv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
 
@@ -370,19 +381,14 @@ struct xpvlv {
 };
 
 struct xpvgv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
 
@@ -394,19 +400,14 @@ struct xpvgv {
 };
 
 struct xpvbm {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
 
@@ -420,19 +421,14 @@ struct xpvbm {
 typedef U16 cv_flags_t;
 
 struct xpvfm {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */
 
@@ -454,19 +450,14 @@ struct xpvfm {
 };
 
 struct xpvio {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+    }          xiv_u;
     MAGIC*     xmg_magic;      /* linked list of magicalness */
     HV*                xmg_stash;      /* class package */