From: Nicholas Clark 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. Deprecated, use C 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 */