From: Nicholas Clark <nick@ccl4.org>
Date: Sat, 21 May 2005 22:46:50 +0000 (+0000)
Subject: Add a union in place of xnv_nv, which allows AVs and HVs to re-use
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e4305a6302fd35f8f8c1a7e612369beaaea58a4a;p=p5sagit%2Fp5-mst-13.2.git

Add a union in place of xnv_nv, which allows AVs and HVs to re-use
the memory to store pointers and integers.
(Part 1 - will be reworked to be more efficient when IV or void*
is 64 bit soon)

p4raw-id: //depot/perl@24538
---

diff --git a/av.h b/av.h
index 186ec35..486bc5c 100644
--- a/av.h
+++ b/av.h
@@ -11,15 +11,25 @@
 struct xpvav {
     SSize_t	xav_fill;       /* Index of last element present */
     SSize_t	xav_max;        /* max index for which array has space */
-    IV		xof_off;	/* ptr is incremented by offset */
-    NV		xnv_nv;		/* numeric value, if any */
+    IV		this_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;
     MAGIC*	xmg_magic;	/* magic for scalar array */
     HV*		xmg_stash;	/* class package */
-
-    SV**	xav_alloc;	/* pointer to beginning of C array of SVs */
-    SV*		xav_arylen;
 };
 
+/* SV**	xav_alloc; */
+#define xav_alloc xnv_u.xnv_s.xnv_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
@@ -56,10 +66,10 @@ Same as C<av_len()>.  Deprecated, use C<av_len()> instead.
 #define Nullav Null(AV*)
 
 #define AvARRAY(av)	((av)->sv_u.sv_array)
-#define AvALLOC(av)	((XPVAV*)  SvANY(av))->xav_alloc
+#define AvALLOC(av)	(*((SV***)&((XPVAV*)  SvANY(av))->xav_alloc))
 #define AvMAX(av)	((XPVAV*)  SvANY(av))->xav_max
 #define AvFILLp(av)	((XPVAV*)  SvANY(av))->xav_fill
-#define AvARYLEN(av)	((XPVAV*)  SvANY(av))->xav_arylen
+#define AvARYLEN(av)	(*((SV**)&((XPVAV*)  SvANY(av))->xav_arylen))
 
 #define AvREAL(av)	(SvFLAGS(av) & SVpav_REAL)
 #define AvREAL_on(av)	(SvFLAGS(av) |= SVpav_REAL)
diff --git a/cv.h b/cv.h
index 90eef1b..ac9d861 100644
--- a/cv.h
+++ b/cv.h
@@ -15,7 +15,16 @@ struct xpvcv {
     STRLEN	xpv_cur;	/* length of xp_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xof_off;	/* integer value */
-    NV		xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* magic for scalar array */
     HV*		xmg_stash;	/* class package */
 
diff --git a/dump.c b/dump.c
index 547af9f..c820687 100644
--- a/dump.c
+++ b/dump.c
@@ -1277,7 +1277,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_IV) {
+    if ((type >= SVt_PVIV && type != SVt_PVAV && type != SVt_PVHV)
+	|| type == SVt_IV) {
 	if (SvIsUV(sv)
 #ifdef PERL_COPY_ON_WRITE
 	               || SvIsCOW(sv)
@@ -1296,7 +1297,8 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
 #endif
 	PerlIO_putc(file, '\n');
     }
-    if (type >= SVt_PVNV || type == SVt_NV) {
+    if ((type >= SVt_PVNV && type != SVt_PVAV && type != SVt_PVHV)
+	|| type == SVt_NV) {
 	STORE_NUMERIC_LOCAL_SET_STANDARD();
 	/* %Vg doesn't work? --jhi */
 #ifdef USE_LONG_DOUBLE
diff --git a/ext/B/B.pm b/ext/B/B.pm
index 84d19dc..2346ac0 100644
--- a/ext/B/B.pm
+++ b/ext/B/B.pm
@@ -848,8 +848,6 @@ IoIFP($io) == PerlIO_stdin() ).
 
 =item MAX
 
-=item OFF
-
 =item ARRAY
 
 =item ARRAYelt
diff --git a/ext/B/B.xs b/ext/B/B.xs
index 0426fcd..782ba9f 100644
--- a/ext/B/B.xs
+++ b/ext/B/B.xs
@@ -1559,12 +1559,6 @@ SSize_t
 AvMAX(av)
 	B::AV	av
 
-#define AvOFF(av) ((XPVAV*)SvANY(av))->xof_off
-
-IV
-AvOFF(av)
-	B::AV	av
-
 void
 AvARRAY(av)
 	B::AV	av
diff --git a/ext/Devel/Peek/t/Peek.t b/ext/Devel/Peek/t/Peek.t
index 7c932d0..c59b9f5 100644
--- a/ext/Devel/Peek/t/Peek.t
+++ b/ext/Devel/Peek/t/Peek.t
@@ -167,8 +167,6 @@ do_test(11,
   SV = PVAV\\($ADDR\\) at $ADDR
     REFCNT = 2
     FLAGS = \\(\\)
-    IV = 0
-    NV = 0
     ARRAY = $ADDR
     FILL = 1
     MAX = 1
@@ -190,8 +188,6 @@ do_test(12,
   SV = PVHV\\($ADDR\\) at $ADDR
     REFCNT = 2
     FLAGS = \\(SHAREKEYS\\)
-    IV = 1
-    NV = $FLOAT
     ARRAY = $ADDR  \\(0:7, 1:1\\)
     hash quality = 100.0%
     KEYS = 1
@@ -286,8 +282,6 @@ do_test(16,
   SV = PVHV\\($ADDR\\) at $ADDR
     REFCNT = 2
     FLAGS = \\(OBJECT,SHAREKEYS\\)
-    IV = 0
-    NV = 0
     STASH = $ADDR\\t"Tac"
     ARRAY = 0x0
     KEYS = 0
@@ -355,8 +349,6 @@ do_test(19,
   SV = PVHV\\($ADDR\\) at $ADDR
     REFCNT = 2
     FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
-    UV = 1
-    NV = $FLOAT
     ARRAY = $ADDR  \\(0:7, 1:1\\)
     hash quality = 100.0%
     KEYS = 1
@@ -381,8 +373,6 @@ do_test(19,
   SV = PVHV\\($ADDR\\) at $ADDR
     REFCNT = 2
     FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
-    UV = 1
-    NV = 0
     ARRAY = $ADDR  \\(0:7, 1:1\\)
     hash quality = 100.0%
     KEYS = 1
diff --git a/hv.h b/hv.h
index 63454b9..60d2eed 100644
--- a/hv.h
+++ b/hv.h
@@ -44,15 +44,26 @@ struct xpvhv_aux {
 struct xpvhv {
     STRLEN	xhv_fill;	/* how full xhv_array currently is */
     STRLEN	xhv_max;	/* subscript of last element of xhv_array */
-    IV		xhv_keys;	/* how many elements in the array */
-    NV		xnv_nv;		/* numeric value, if any */
+    IV		for_rent;
+    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;
     MAGIC*	xmg_magic;	/* magic for scalar array */
     HV*		xmg_stash;	/* class package */
-
-    struct xpvhv_aux* xhv_aux;
     /* list of pm's for this package is now stored in symtab magic.  */
 };
 
+#define xhv_aux xnv_u.xnv_s.xnv_p1
+#define xhv_keys xnv_u.xnv_s.xnv_u2.xnv_i2
+
+
 /* hash a key */
 /* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins
  * from requirements by Colin Plumb.
diff --git a/sv.h b/sv.h
index 04fef7c..5f4a262 100644
--- a/sv.h
+++ b/sv.h
@@ -295,15 +295,35 @@ struct xpvnv {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV    	xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
 };
 
+#define xnv_nv xnv_u.xnvu_nv
+
 /* These structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV    	xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 };
@@ -312,7 +332,16 @@ struct xpvlv {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV    	xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -334,7 +363,16 @@ struct xpvgv {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV		xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -349,7 +387,16 @@ struct xpvbm {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV		xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -366,7 +413,16 @@ struct xpvfm {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV		xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -391,7 +447,16 @@ struct xpvio {
     STRLEN	xpv_cur;	/* length of sv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    NV		xnv_nv;		/* numeric value, if any */
+    union {
+	NV	xnvu_nv;	/* numeric value, if any */
+	struct {
+	    void *xnv_p1;
+	    union {
+		void *xnv_p2;
+		IV xnv_i2;
+	    }	xnv_u2;
+	}	xnv_s;
+    }		xnv_u;
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */