diff options
author | Nicholas Clark <nick@ccl4.org> | 2005-05-21 18:19:43 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2005-05-21 18:19:43 +0000 |
commit | 7b2c381cf37e4e4611c4a864b5d6f7134344e3e6 (patch) | |
tree | 8807ac10b976a808e6707f79fbff58de3476795c | |
parent | 6e3207c2a1cd2d1644ac48e4d8ddd6742391e423 (diff) | |
download | perl-7b2c381cf37e4e4611c4a864b5d6f7134344e3e6.tar.gz |
Move the xpv_pv/xrv_rv member into the SV head, in a union with
IV and UV. Avoid allocating a body for IVs and RVs.
p4raw-id: //depot/perl@24531
-rw-r--r-- | av.h | 3 | ||||
-rw-r--r-- | bytecode.pl | 13 | ||||
-rw-r--r-- | cv.h | 1 | ||||
-rw-r--r-- | embed.fnc | 4 | ||||
-rw-r--r-- | embed.h | 8 | ||||
-rw-r--r-- | ext/B/B/C.pm | 1 | ||||
-rw-r--r-- | ext/ByteLoader/bytecode.h | 32 | ||||
-rw-r--r-- | ext/ByteLoader/byterun.c | 6 | ||||
-rw-r--r-- | ext/ByteLoader/byterun.h | 7 | ||||
-rw-r--r-- | hv.c | 80 | ||||
-rw-r--r-- | hv.h | 3 | ||||
-rw-r--r-- | proto.h | 4 | ||||
-rw-r--r-- | sv.c | 317 | ||||
-rw-r--r-- | sv.h | 98 |
14 files changed, 234 insertions, 343 deletions
@@ -9,7 +9,6 @@ */ struct xpvav { - char* xav_array; /* pointer to first array element */ 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 */ @@ -56,7 +55,7 @@ Same as C<av_len()>. Deprecated, use C<av_len()> instead. #define Nullav Null(AV*) -#define AvARRAY(av) ((SV**)((XPVAV*) SvANY(av))->xav_array) +#define AvARRAY(av) ((av)->sv_u.sv_array) #define AvALLOC(av) ((XPVAV*) SvANY(av))->xav_alloc #define AvMAX(av) ((XPVAV*) SvANY(av))->xav_max #define AvFILLp(av) ((XPVAV*) SvANY(av))->xav_fill diff --git a/bytecode.pl b/bytecode.pl index 5747eaede3..1a090af983 100644 --- a/bytecode.pl +++ b/bytecode.pl @@ -212,13 +212,18 @@ struct byteloader_fdata { int idx; }; +struct byteloader_pv_state { + char *pvx; + XPV xpv; +}; + struct byteloader_state { struct byteloader_fdata *bs_fdata; SV *bs_sv; void **bs_obj_list; int bs_obj_list_fill; int bs_ix; - XPV bs_pv; + struct byteloader_pv_state bs_pv; int bs_iv_overflows; }; @@ -361,7 +366,7 @@ ldsv bstate->bs_sv svindex ldop PL_op opindex stsv bstate->bs_sv U32 s stop PL_op U32 s -stpv bstate->bs_pv.xpv_pv U32 x +stpv bstate->bs_pv.pvx U32 x ldspecsv bstate->bs_sv U8 x ldspecsvx bstate->bs_sv U8 x newsv bstate->bs_sv U8 x @@ -370,8 +375,8 @@ newop PL_op U8 x newopx PL_op U16 x newopn PL_op U8 x newpv none PV -pv_cur bstate->bs_pv.xpv_cur STRLEN -pv_free bstate->bs_pv none x +pv_cur bstate->bs_pv.xpv.xpv_cur STRLEN +pv_free bstate->bs_pv.pvx none x sv_upgrade bstate->bs_sv U8 x sv_refcnt SvREFCNT(bstate->bs_sv) U32 sv_refcnt_add SvREFCNT(bstate->bs_sv) I32 x @@ -12,7 +12,6 @@ * in sv.h */ struct xpvcv { - char * xpv_pv; /* pointer to malloced string (for prototype) */ STRLEN xpv_cur; /* length of xp_pv as a C string */ STRLEN xpv_len; /* allocated size */ IV xof_off; /* integer value */ @@ -1180,7 +1180,6 @@ s |SV* |save_scalar_at |SV **sptr #if defined(PERL_IN_SV_C) || defined(PERL_DECL_PROT) s |IV |asIV |SV* sv s |UV |asUV |SV* sv -s |XPVIV* |new_xiv s |XPVNV* |new_xnv s |XPV* |new_xpv s |XPVIV* |new_xpviv @@ -1192,8 +1191,6 @@ s |XPVMG* |new_xpvmg s |XPVGV* |new_xpvgv s |XPVLV* |new_xpvlv s |XPVBM* |new_xpvbm -s |XRV* |new_xrv -s |void |del_xiv |XPVIV* p s |void |del_xnv |XPVNV* p s |void |del_xpv |XPV* p s |void |del_xpviv |XPVIV* p @@ -1205,7 +1202,6 @@ s |void |del_xpvmg |XPVMG* p s |void |del_xpvgv |XPVGV* p s |void |del_xpvlv |XPVLV* p s |void |del_xpvbm |XPVBM* p -s |void |del_xrv |XRV* p s |void |sv_unglob |SV* sv s |void |not_a_number |SV *sv s |I32 |visit |SVFUNC_t f|U32 flags|U32 mask @@ -1241,7 +1241,6 @@ #ifdef PERL_CORE #define asIV S_asIV #define asUV S_asUV -#define new_xiv S_new_xiv #define new_xnv S_new_xnv #define new_xpv S_new_xpv #define new_xpviv S_new_xpviv @@ -1253,8 +1252,6 @@ #define new_xpvgv S_new_xpvgv #define new_xpvlv S_new_xpvlv #define new_xpvbm S_new_xpvbm -#define new_xrv S_new_xrv -#define del_xiv S_del_xiv #define del_xnv S_del_xnv #define del_xpv S_del_xpv #define del_xpviv S_del_xpviv @@ -1266,7 +1263,6 @@ #define del_xpvgv S_del_xpvgv #define del_xpvlv S_del_xpvlv #define del_xpvbm S_del_xpvbm -#define del_xrv S_del_xrv #define sv_unglob S_sv_unglob #define not_a_number S_not_a_number #define visit S_visit @@ -3189,7 +3185,6 @@ #ifdef PERL_CORE #define asIV(a) S_asIV(aTHX_ a) #define asUV(a) S_asUV(aTHX_ a) -#define new_xiv() S_new_xiv(aTHX) #define new_xnv() S_new_xnv(aTHX) #define new_xpv() S_new_xpv(aTHX) #define new_xpviv() S_new_xpviv(aTHX) @@ -3201,8 +3196,6 @@ #define new_xpvgv() S_new_xpvgv(aTHX) #define new_xpvlv() S_new_xpvlv(aTHX) #define new_xpvbm() S_new_xpvbm(aTHX) -#define new_xrv() S_new_xrv(aTHX) -#define del_xiv(a) S_del_xiv(aTHX_ a) #define del_xnv(a) S_del_xnv(aTHX_ a) #define del_xpv(a) S_del_xpv(aTHX_ a) #define del_xpviv(a) S_del_xpviv(aTHX_ a) @@ -3214,7 +3207,6 @@ #define del_xpvgv(a) S_del_xpvgv(aTHX_ a) #define del_xpvlv(a) S_del_xpvlv(aTHX_ a) #define del_xpvbm(a) S_del_xpvbm(aTHX_ a) -#define del_xrv(a) S_del_xrv(aTHX_ a) #define sv_unglob(a) S_sv_unglob(aTHX_ a) #define not_a_number(a) S_not_a_number(aTHX_ a) #define visit(a,b,c) S_visit(aTHX_ a,b,c) diff --git a/ext/B/B/C.pm b/ext/B/B/C.pm index 906c1a4e9c..51b357ef52 100644 --- a/ext/B/B/C.pm +++ b/ext/B/B/C.pm @@ -1416,7 +1416,6 @@ sub output_declarations { * Some pre-Standard compilers can't cope with initialising unions. Ho hum. */ typedef struct { - char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xp_pv as a C string */ STRLEN xpv_len; /* allocated size */ IV xof_off; /* integer value */ diff --git a/ext/ByteLoader/bytecode.h b/ext/ByteLoader/bytecode.h index 40c1e992d6..087e1511ad 100644 --- a/ext/ByteLoader/bytecode.h +++ b/ext/ByteLoader/bytecode.h @@ -31,14 +31,14 @@ typedef char *pvindex; #define BGET_PV(arg) STMT_START { \ BGET_U32(arg); \ if (arg) { \ - New(666, bstate->bs_pv.xpv_pv, arg, char); \ - bl_read(bstate->bs_fdata, bstate->bs_pv.xpv_pv, arg, 1); \ - bstate->bs_pv.xpv_len = arg; \ - bstate->bs_pv.xpv_cur = arg - 1; \ + New(666, bstate->bs_pv.pvx, arg, char); \ + bl_read(bstate->bs_fdata, bstate->bs_pv.pvx, arg, 1); \ + bstate->bs_pv.xpv.xpv_len = arg; \ + bstate->bs_pv.xpv.xpv_cur = arg - 1; \ } else { \ - bstate->bs_pv.xpv_pv = 0; \ - bstate->bs_pv.xpv_len = 0; \ - bstate->bs_pv.xpv_cur = 0; \ + bstate->bs_pv.pvx = 0; \ + bstate->bs_pv.xpv.xpv_len = 0; \ + bstate->bs_pv.xpv.xpv_cur = 0; \ } \ } STMT_END @@ -68,7 +68,7 @@ typedef char *pvindex; arg = (char *) ary; \ } while (0) -#define BGET_pvcontents(arg) arg = bstate->bs_pv.xpv_pv +#define BGET_pvcontents(arg) arg = bstate->bs_pv.pvx #define BGET_strconst(arg) STMT_START { \ for (arg = PL_tokenbuf; (*arg = BGET_FGETC()); arg++) /* nothing */; \ arg = PL_tokenbuf; \ @@ -122,7 +122,7 @@ typedef char *pvindex; } STMT_END #define BSET_sv_magic(sv, arg) sv_magic(sv, Nullsv, arg, 0, 0) -#define BSET_mg_name(mg, arg) mg->mg_ptr = arg; mg->mg_len = bstate->bs_pv.xpv_cur +#define BSET_mg_name(mg, arg) mg->mg_ptr = arg; mg->mg_len = bstate->bs_pv.xpv.xpv_cur #define BSET_mg_namex(mg, arg) \ (mg->mg_ptr = (char*)SvREFCNT_inc((SV*)arg), \ mg->mg_len = HEf_SVKEY) @@ -130,9 +130,9 @@ typedef char *pvindex; #define BSET_sv_upgrade(sv, arg) (void)SvUPGRADE(sv, arg) #define BSET_xrv(sv, arg) SvRV_set(sv, arg) #define BSET_xpv(sv) do { \ - SvPV_set(sv, bstate->bs_pv.xpv_pv); \ - SvCUR_set(sv, bstate->bs_pv.xpv_cur); \ - SvLEN_set(sv, bstate->bs_pv.xpv_len); \ + SvPV_set(sv, bstate->bs_pv.pvx); \ + SvCUR_set(sv, bstate->bs_pv.xpv.xpv_cur); \ + SvLEN_set(sv, bstate->bs_pv.xpv.xpv_len); \ } while (0) #define BSET_xpv_cur(sv, arg) SvCUR_set(sv, arg) #define BSET_xpv_len(sv, arg) SvLEN_set(sv, arg) @@ -144,8 +144,8 @@ typedef char *pvindex; #define BSET_av_push(sv, arg) av_push((AV*)sv, arg) #define BSET_av_pushx(sv, arg) (AvARRAY(sv)[++AvFILLp(sv)] = arg) #define BSET_hv_store(sv, arg) \ - hv_store((HV*)sv, bstate->bs_pv.xpv_pv, bstate->bs_pv.xpv_cur, arg, 0) -#define BSET_pv_free(pv) Safefree(pv.xpv_pv) + hv_store((HV*)sv, bstate->bs_pv.pvx, bstate->bs_pv.xpv.xpv_cur, arg, 0) +#define BSET_pv_free(p) Safefree(p) #ifdef USE_ITHREADS @@ -155,7 +155,7 @@ typedef char *pvindex; STMT_START { \ SV* repointer; \ REGEXP* rx = arg ? \ - CALLREGCOMP(aTHX_ arg, arg + bstate->bs_pv.xpv_cur, cPMOPx(o)) : \ + CALLREGCOMP(aTHX_ arg, arg + bstate->bs_pv.xpv.xpv_cur, cPMOPx(o)) : \ Null(REGEXP*); \ if(av_len((AV*) PL_regex_pad[0]) > -1) { \ repointer = av_pop((AV*)PL_regex_pad[0]); \ @@ -174,7 +174,7 @@ typedef char *pvindex; #define BSET_pregcomp(o, arg) \ STMT_START { \ PM_SETRE(((PMOP*)o), (arg ? \ - CALLREGCOMP(aTHX_ arg, arg + bstate->bs_pv.xpv_cur, cPMOPx(o)): \ + CALLREGCOMP(aTHX_ arg, arg + bstate->bs_pv.xpv.xpv_cur, cPMOPx(o)): \ Null(REGEXP*))); \ } STMT_END diff --git a/ext/ByteLoader/byterun.c b/ext/ByteLoader/byterun.c index 4506066279..7a8d378d50 100644 --- a/ext/ByteLoader/byterun.c +++ b/ext/ByteLoader/byterun.c @@ -116,7 +116,7 @@ byterun(pTHX_ register struct byteloader_state *bstate) { U32 arg; BGET_U32(arg); - BSET_stpv(bstate->bs_pv.xpv_pv, arg); + BSET_stpv(bstate->bs_pv.pvx, arg); break; } case INSN_LDSPECSV: /* 6 */ @@ -178,12 +178,12 @@ byterun(pTHX_ register struct byteloader_state *bstate) { STRLEN arg; BGET_PADOFFSET(arg); - bstate->bs_pv.xpv_cur = arg; + bstate->bs_pv.xpv.xpv_cur = arg; break; } case INSN_PV_FREE: /* 16 */ { - BSET_pv_free(bstate->bs_pv); + BSET_pv_free(bstate->bs_pv.pvx); break; } case INSN_SV_UPGRADE: /* 17 */ diff --git a/ext/ByteLoader/byterun.h b/ext/ByteLoader/byterun.h index dcd3374620..0ba48c6153 100644 --- a/ext/ByteLoader/byterun.h +++ b/ext/ByteLoader/byterun.h @@ -15,13 +15,18 @@ struct byteloader_fdata { int idx; }; +struct byteloader_pv_state { + char *pvx; + XPV xpv; +}; + struct byteloader_state { struct byteloader_fdata *bs_fdata; SV *bs_sv; void **bs_obj_list; int bs_obj_list_fill; int bs_ix; - XPV bs_pv; + struct byteloader_pv_state bs_pv; int bs_iv_overflows; }; @@ -542,7 +542,7 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } TAINT_IF(save_taint); - if (!xhv->xhv_array /* !HvARRAY(hv) */ && !needs_store) { + if (!HvARRAY(hv) && !needs_store) { if (flags & HVhek_FREEKEY) Safefree(key); return Nullhe; @@ -568,15 +568,15 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } /* ISSTORE */ } /* SvMAGICAL */ - if (!xhv->xhv_array /* !HvARRAY(hv) */) { + if (!HvARRAY(hv)) { if ((action & (HV_FETCH_LVALUE | HV_FETCH_ISSTORE)) #ifdef DYNAMIC_ENV_FETCH /* if it's an %ENV lookup, we may get it on the fly */ || (SvRMAGICAL((SV*)hv) && mg_find((SV*)hv, PERL_MAGIC_env)) #endif ) - Newz(503, xhv->xhv_array /* HvARRAY(hv) */, + Newz(503, HvARRAY(hv), PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), - char); + HE*); #ifdef DYNAMIC_ENV_FETCH else if (action & HV_FETCH_ISEXISTS) { /* for an %ENV exists, if we do an insert it's by a recursive @@ -626,12 +626,11 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, n_links = 0; #ifdef DYNAMIC_ENV_FETCH - if (!xhv->xhv_array /* !HvARRAY(hv) */) entry = Null(HE*); + if (!HvARRAY(hv)) entry = Null(HE*); else #endif { - /* entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ - entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; } for (; entry; ++n_links, entry = HeNEXT(entry)) { if (HeHASH(entry) != hash) /* strings can't be equal */ @@ -741,16 +740,16 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, /* Welcome to hv_store... */ - if (!xhv->xhv_array) { + if (!HvARRAY(hv)) { /* Not sure if we can get here. I think the only case of oentry being NULL is for %ENV with dynamic env fetch. But that should disappear with magic in the previous code. */ - Newz(503, xhv->xhv_array /* HvARRAY(hv) */, + Newz(503, HvARRAY(hv), PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), - char); + HE*); } - oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + oentry = &(HvARRAY(hv))[hash & (I32) xhv->xhv_max]; entry = new_HE(); /* share_hek_flags will do the free for us. This might be considered @@ -941,7 +940,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } } xhv = (XPVHV*)SvANY(hv); - if (!xhv->xhv_array /* !HvARRAY(hv) */) + if (!HvARRAY(hv)) return Nullsv; if (is_utf8) { @@ -975,8 +974,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, masked_flags = (k_flags & HVhek_MASK); - /* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ - oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; entry = *oentry; i = 1; for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) { @@ -1056,7 +1054,7 @@ S_hsplit(pTHX_ HV *hv) const I32 oldsize = (I32) xhv->xhv_max+1; /* HvMAX(hv)+1 (sick) */ register I32 newsize = oldsize * 2; register I32 i; - register char *a = xhv->xhv_array; /* HvARRAY(hv) */ + char *a = (char*) HvARRAY(hv); register HE **aep; register HE **oentry; int longest_chain = 0; @@ -1086,19 +1084,19 @@ S_hsplit(pTHX_ HV *hv) PL_nomemok = FALSE; return; } - Copy(xhv->xhv_array /* HvARRAY(hv) */, a, oldsize * sizeof(HE*), char); + Copy(HvARRAY(hv), a, oldsize * sizeof(HE*), char); if (oldsize >= 64) { - offer_nice_chunk(xhv->xhv_array /* HvARRAY(hv) */, + offer_nice_chunk(HvARRAY(hv), PERL_HV_ARRAY_ALLOC_BYTES(oldsize)); } else - Safefree(xhv->xhv_array /* HvARRAY(hv) */); + Safefree(HvARRAY(hv)); #endif PL_nomemok = FALSE; Zero(&a[oldsize * sizeof(HE*)], (newsize-oldsize) * sizeof(HE*), char); /* zero 2nd half*/ xhv->xhv_max = --newsize; /* HvMAX(hv) = --newsize */ - xhv->xhv_array = a; /* HvARRAY(hv) = a */ + HvARRAY(hv) = (HE**) a; aep = (HE**)a; for (i=0; i<oldsize; i++,aep++) { @@ -1161,7 +1159,7 @@ S_hsplit(pTHX_ HV *hv) HvSHAREKEYS_off(hv); HvREHASH_on(hv); - aep = (HE **) xhv->xhv_array; + aep = HvARRAY(hv); for (i=0; i<newsize; i++,aep++) { register HE *entry = *aep; @@ -1200,8 +1198,8 @@ S_hsplit(pTHX_ HV *hv) entry = next; } } - Safefree (xhv->xhv_array); - xhv->xhv_array = a; /* HvARRAY(hv) = a */ + Safefree (HvARRAY(hv)); + HvARRAY(hv) = (HE **)a; } void @@ -1227,7 +1225,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax) if (newsize < newmax) return; /* overflow detection */ - a = xhv->xhv_array; /* HvARRAY(hv) */ + a = (char *) HvARRAY(hv); if (a) { PL_nomemok = TRUE; #if defined(STRANGE_MALLOC) || defined(MYMALLOC) @@ -1242,13 +1240,13 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax) PL_nomemok = FALSE; return; } - Copy(xhv->xhv_array /* HvARRAY(hv) */, a, oldsize * sizeof(HE*), char); + Copy(HvARRAY(hv), a, oldsize * sizeof(HE*), char); if (oldsize >= 64) { - offer_nice_chunk(xhv->xhv_array /* HvARRAY(hv) */, + offer_nice_chunk(HvARRAY(hv), PERL_HV_ARRAY_ALLOC_BYTES(oldsize)); } else - Safefree(xhv->xhv_array /* HvARRAY(hv) */); + Safefree(HvARRAY(hv)); #endif PL_nomemok = FALSE; Zero(&a[oldsize * sizeof(HE*)], (newsize-oldsize) * sizeof(HE*), char); /* zero 2nd half*/ @@ -1257,7 +1255,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax) Newz(0, a, PERL_HV_ARRAY_ALLOC_BYTES(newsize), char); } xhv->xhv_max = --newsize; /* HvMAX(hv) = --newsize */ - xhv->xhv_array = a; /* HvARRAY(hv) = a */ + HvARRAY(hv) = (HE **) a; if (!xhv->xhv_fill /* !HvFILL(hv) */) /* skip rest if no entries */ return; @@ -1451,11 +1449,11 @@ Perl_hv_clear(pTHX_ HV *hv) xhv = (XPVHV*)SvANY(hv); - if (SvREADONLY(hv) && xhv->xhv_array != NULL) { + if (SvREADONLY(hv) && HvARRAY(hv) != NULL) { /* restricted hash: convert all keys to placeholders */ I32 i; for (i = 0; i <= (I32) xhv->xhv_max; i++) { - HE *entry = ((HE**)xhv->xhv_array)[i]; + HE *entry = (HvARRAY(hv))[i]; for (; entry; entry = HeNEXT(entry)) { /* not already placeholder */ if (HeVAL(entry) != &PL_sv_placeholder) { @@ -1476,8 +1474,8 @@ Perl_hv_clear(pTHX_ HV *hv) hfreeentries(hv); HvPLACEHOLDERS_set(hv, 0); - if (xhv->xhv_array /* HvARRAY(hv) */) - (void)memzero(xhv->xhv_array /* HvARRAY(hv) */, + if (HvARRAY(hv)) + (void)memzero(HvARRAY(hv), (xhv->xhv_max+1 /* HvMAX(hv)+1 */) * sizeof(HE*)); if (SvRMAGICAL(hv)) @@ -1621,7 +1619,7 @@ Perl_hv_undef(pTHX_ HV *hv) DEBUG_A(Perl_hv_assert(aTHX_ hv)); xhv = (XPVHV*)SvANY(hv); hfreeentries(hv); - Safefree(xhv->xhv_array /* HvARRAY(hv) */); + Safefree(HvARRAY(hv)); if ((name = HvNAME_get(hv))) { /* FIXME - strlen HvNAME */ if(PL_stashcache) @@ -1629,7 +1627,7 @@ Perl_hv_undef(pTHX_ HV *hv) Perl_hv_name_set(aTHX_ hv, 0, 0, 0); } xhv->xhv_max = 7; /* HvMAX(hv) = 7 (it's a normal hash) */ - xhv->xhv_array = 0; /* HvARRAY(hv) = 0 */ + HvARRAY(hv) = 0; HvPLACEHOLDERS_set(hv, 0); if (SvRMAGICAL(hv)) @@ -1881,10 +1879,13 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) prime_env_iter(); #endif - if (!xhv->xhv_array /* !HvARRAY(hv) */) - Newz(506, xhv->xhv_array /* HvARRAY(hv) */, + if (!HvARRAY(hv)) { + char *darray; + Newz(506, darray, PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), char); + HvARRAY(hv) = (HE**) darray; + } /* At start of hash, entry is NULL. */ if (entry) { @@ -1908,8 +1909,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ break; } - /* entry = (HvARRAY(hv))[HvRITER(hv)]; */ - entry = ((HE**)xhv->xhv_array)[iter->xhv_riter]; + entry = (HvARRAY(hv))[iter->xhv_riter]; if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { /* If we have an entry, but it's a placeholder, don't count it. @@ -2129,8 +2129,7 @@ S_unshare_hek_or_pvn(pTHX_ HEK *hek, const char *str, I32 len, U32 hash) xhv = (XPVHV*)SvANY(PL_strtab); /* assert(xhv_array != 0) */ LOCK_STRTAB_MUTEX; - /* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ - oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + oentry = &(HvARRAY(PL_strtab))[hash & (I32) HvMAX(PL_strtab)]; if (hek) { for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) { if (HeKEY_hek(entry) != hek) @@ -2228,8 +2227,7 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags) xhv = (XPVHV*)SvANY(PL_strtab); /* assert(xhv_array != 0) */ LOCK_STRTAB_MUTEX; - /* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ - oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + oentry = &(HvARRAY(PL_strtab))[hash & (I32) HvMAX(PL_strtab)]; for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) { if (HeHASH(entry) != hash) /* strings can't be equal */ continue; @@ -42,7 +42,6 @@ struct xpvhv_aux { /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { - char * xhv_array; /* pointer to malloced string */ 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 */ @@ -183,7 +182,7 @@ C<SV*>. #define Nullhv Null(HV*) -#define HvARRAY(hv) (*(HE***)&((XPVHV*) SvANY(hv))->xhv_array) +#define HvARRAY(hv) (*(HE***)&((hv)->sv_u.sv_array)) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill #define HvMAX(hv) ((XPVHV*) SvANY(hv))->xhv_max #define HvRITER(hv) (*Perl_hv_riter_p(aTHX_ (HV*)(hv))) @@ -2053,7 +2053,6 @@ STATIC SV* S_save_scalar_at(pTHX_ SV **sptr); #if defined(PERL_IN_SV_C) || defined(PERL_DECL_PROT) STATIC IV S_asIV(pTHX_ SV* sv); STATIC UV S_asUV(pTHX_ SV* sv); -STATIC XPVIV* S_new_xiv(pTHX); STATIC XPVNV* S_new_xnv(pTHX); STATIC XPV* S_new_xpv(pTHX); STATIC XPVIV* S_new_xpviv(pTHX); @@ -2065,8 +2064,6 @@ STATIC XPVMG* S_new_xpvmg(pTHX); STATIC XPVGV* S_new_xpvgv(pTHX); STATIC XPVLV* S_new_xpvlv(pTHX); STATIC XPVBM* S_new_xpvbm(pTHX); -STATIC XRV* S_new_xrv(pTHX); -STATIC void S_del_xiv(pTHX_ XPVIV* p); STATIC void S_del_xnv(pTHX_ XPVNV* p); STATIC void S_del_xpv(pTHX_ XPV* p); STATIC void S_del_xpviv(pTHX_ XPVIV* p); @@ -2078,7 +2075,6 @@ STATIC void S_del_xpvmg(pTHX_ XPVMG* p); STATIC void S_del_xpvgv(pTHX_ XPVGV* p); STATIC void S_del_xpvlv(pTHX_ XPVLV* p); STATIC void S_del_xpvbm(pTHX_ XPVBM* p); -STATIC void S_del_xrv(pTHX_ XRV* p); STATIC void S_sv_unglob(pTHX_ SV* sv); STATIC void S_not_a_number(pTHX_ SV *sv); STATIC I32 S_visit(pTHX_ SVFUNC_t f, U32 flags, U32 mask); @@ -523,7 +523,7 @@ Perl_sv_free_arenas(pTHX) { SV* sva; SV* svanext; - XPV *arena, *arenanext; + void *arena, *arenanext; /* Free arenas here, but be careful about fake ones. (We assume contiguity of the fake ones with the corresponding real ones.) */ @@ -537,92 +537,78 @@ Perl_sv_free_arenas(pTHX) Safefree((void *)sva); } - for (arena = PL_xiv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; - Safefree(arena); - } - PL_xiv_arenaroot = 0; - PL_xiv_root = 0; - for (arena = PL_xnv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + arenanext = *(void **)arena; Safefree(arena); } PL_xnv_arenaroot = 0; PL_xnv_root = 0; - for (arena = PL_xrv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; - Safefree(arena); - } - PL_xrv_arenaroot = 0; - PL_xrv_root = 0; - for (arena = PL_xpv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + arenanext = *(void **)arena; Safefree(arena); } PL_xpv_arenaroot = 0; PL_xpv_root = 0; - for (arena = (XPV*)PL_xpviv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpviv_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpviv_arenaroot = 0; PL_xpviv_root = 0; - for (arena = (XPV*)PL_xpvnv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvnv_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvnv_arenaroot = 0; PL_xpvnv_root = 0; - for (arena = (XPV*)PL_xpvcv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvcv_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvcv_arenaroot = 0; PL_xpvcv_root = 0; - for (arena = (XPV*)PL_xpvav_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvav_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvav_arenaroot = 0; PL_xpvav_root = 0; - for (arena = (XPV*)PL_xpvhv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvhv_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvhv_arenaroot = 0; PL_xpvhv_root = 0; - for (arena = (XPV*)PL_xpvmg_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvmg_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvmg_arenaroot = 0; PL_xpvmg_root = 0; - for (arena = (XPV*)PL_xpvgv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvgv_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvgv_arenaroot = 0; PL_xpvgv_root = 0; - for (arena = (XPV*)PL_xpvlv_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvlv_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvlv_arenaroot = 0; PL_xpvlv_root = 0; - for (arena = (XPV*)PL_xpvbm_arenaroot; arena; arena = arenanext) { - arenanext = (XPV*)arena->xpv_pv; + for (arena = PL_xpvbm_arenaroot; arena; arena = arenanext) { + arenanext = *(void **)arena; Safefree(arena); } PL_xpvbm_arenaroot = 0; @@ -1139,53 +1125,6 @@ Perl_report_uninit(pTHX_ SV* uninit_sv) "", "", ""); } - -/* allocate another arena's worth of struct xrv */ - -STATIC void -S_more_xrv(pTHX) -{ - XRV* xrv; - XRV* xrvend; - XPV *ptr; - New(712, ptr, PERL_ARENA_SIZE/sizeof(XPV), XPV); - ptr->xpv_pv = (char*)PL_xrv_arenaroot; - PL_xrv_arenaroot = ptr; - - xrv = (XRV*) ptr; - xrvend = &xrv[PERL_ARENA_SIZE / sizeof(XRV) - 1]; - xrv += (sizeof(XPV) - 1) / sizeof(XRV) + 1; - PL_xrv_root = xrv; - while (xrv < xrvend) { - xrv->xrv_rv = (SV*)(xrv + 1); - xrv++; - } - xrv->xrv_rv = 0; -} - -/* allocate another arena's worth of IV bodies */ - -STATIC void -S_more_xiv(pTHX) -{ - IV* xiv; - IV* xivend; - XPV* ptr; - New(705, ptr, PERL_ARENA_SIZE/sizeof(XPV), XPV); - ptr->xpv_pv = (char*)PL_xiv_arenaroot; /* linked list of xiv arenas */ - PL_xiv_arenaroot = ptr; /* to keep Purify happy */ - - xiv = (IV*) ptr; - xivend = &xiv[PERL_ARENA_SIZE / sizeof(IV) - 1]; - xiv += (sizeof(XPV) - 1) / sizeof(IV) + 1; /* fudge by size of XPV */ - PL_xiv_root = xiv; - while (xiv < xivend) { - *(IV**)xiv = (IV *)(xiv + 1); - xiv++; - } - *(IV**)xiv = 0; -} - /* allocate another arena's worth of NV bodies */ STATIC void @@ -1193,9 +1132,9 @@ S_more_xnv(pTHX) { NV* xnv; NV* xnvend; - XPV *ptr; - New(711, ptr, PERL_ARENA_SIZE/sizeof(XPV), XPV); - ptr->xpv_pv = (char*)PL_xnv_arenaroot; + void *ptr; + New(711, ptr, PERL_ARENA_SIZE/sizeof(NV), NV); + *((void **) ptr) = (void *)PL_xnv_arenaroot; PL_xnv_arenaroot = ptr; xnv = (NV*) ptr; @@ -1217,16 +1156,16 @@ S_more_xpv(pTHX) XPV* xpv; XPV* xpvend; New(713, xpv, PERL_ARENA_SIZE/sizeof(XPV), XPV); - xpv->xpv_pv = (char*)PL_xpv_arenaroot; + *((XPV**)xpv) = PL_xpv_arenaroot; PL_xpv_arenaroot = xpv; xpvend = &xpv[PERL_ARENA_SIZE / sizeof(XPV) - 1]; PL_xpv_root = ++xpv; while (xpv < xpvend) { - xpv->xpv_pv = (char*)(xpv + 1); + *((XPV**)xpv) = xpv + 1; xpv++; } - xpv->xpv_pv = 0; + *((XPV**)xpv) = 0; } /* allocate another arena's worth of struct xpviv */ @@ -1237,16 +1176,16 @@ S_more_xpviv(pTHX) XPVIV* xpviv; XPVIV* xpvivend; New(714, xpviv, PERL_ARENA_SIZE/sizeof(XPVIV), XPVIV); - xpviv->xpv_pv = (char*)PL_xpviv_arenaroot; + *((XPVIV**)xpviv) = PL_xpviv_arenaroot; PL_xpviv_arenaroot = xpviv; xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(XPVIV) - 1]; PL_xpviv_root = ++xpviv; while (xpviv < xpvivend) { - xpviv->xpv_pv = (char*)(xpviv + 1); + *((XPVIV**)xpviv) = xpviv + 1; xpviv++; } - xpviv->xpv_pv = 0; + *((XPVIV**)xpviv) = 0; } /* allocate another arena's worth of struct xpvnv */ @@ -1257,16 +1196,16 @@ S_more_xpvnv(pTHX) XPVNV* xpvnv; XPVNV* xpvnvend; New(715, xpvnv, PERL_ARENA_SIZE/sizeof(XPVNV), XPVNV); - xpvnv->xpv_pv = (char*)PL_xpvnv_arenaroot; + *((XPVNV**)xpvnv) = PL_xpvnv_arenaroot; PL_xpvnv_arenaroot = xpvnv; xpvnvend = &xpvnv[PERL_ARENA_SIZE / sizeof(XPVNV) - 1]; PL_xpvnv_root = ++xpvnv; while (xpvnv < xpvnvend) { - xpvnv->xpv_pv = (char*)(xpvnv + 1); + *((XPVNV**)xpvnv) = xpvnv + 1; xpvnv++; } - xpvnv->xpv_pv = 0; + *((XPVNV**)xpvnv) = 0; } /* allocate another arena's worth of struct xpvcv */ @@ -1277,16 +1216,16 @@ S_more_xpvcv(pTHX) XPVCV* xpvcv; XPVCV* xpvcvend; New(716, xpvcv, PERL_ARENA_SIZE/sizeof(XPVCV), XPVCV); - xpvcv->xpv_pv = (char*)PL_xpvcv_arenaroot; + *((XPVCV**)xpvcv) = PL_xpvcv_arenaroot; PL_xpvcv_arenaroot = xpvcv; xpvcvend = &xpvcv[PERL_ARENA_SIZE / sizeof(XPVCV) - 1]; PL_xpvcv_root = ++xpvcv; while (xpvcv < xpvcvend) { - xpvcv->xpv_pv = (char*)(xpvcv + 1); + *((XPVCV**)xpvcv) = xpvcv + 1; xpvcv++; } - xpvcv->xpv_pv = 0; + *((XPVCV**)xpvcv) = 0; } /* allocate another arena's worth of struct xpvav */ @@ -1297,16 +1236,16 @@ S_more_xpvav(pTHX) XPVAV* xpvav; XPVAV* xpvavend; New(717, xpvav, PERL_ARENA_SIZE/sizeof(XPVAV), XPVAV); - xpvav->xav_array = (char*)PL_xpvav_arenaroot; + *((XPVAV**)xpvav) = PL_xpvav_arenaroot; PL_xpvav_arenaroot = xpvav; xpvavend = &xpvav[PERL_ARENA_SIZE / sizeof(XPVAV) - 1]; PL_xpvav_root = ++xpvav; while (xpvav < xpvavend) { - xpvav->xav_array = (char*)(xpvav + 1); + *((XPVAV**)xpvav) = xpvav + 1; xpvav++; } - xpvav->xav_array = 0; + *((XPVAV**)xpvav) = 0; } /* allocate another arena's worth of struct xpvhv */ @@ -1317,16 +1256,16 @@ S_more_xpvhv(pTHX) XPVHV* xpvhv; XPVHV* xpvhvend; New(718, xpvhv, PERL_ARENA_SIZE/sizeof(XPVHV), XPVHV); - xpvhv->xhv_array = (char*)PL_xpvhv_arenaroot; + *((XPVHV**)xpvhv) = PL_xpvhv_arenaroot; PL_xpvhv_arenaroot = xpvhv; xpvhvend = &xpvhv[PERL_ARENA_SIZE / sizeof(XPVHV) - 1]; PL_xpvhv_root = ++xpvhv; while (xpvhv < xpvhvend) { - xpvhv->xhv_array = (char*)(xpvhv + 1); + *((XPVHV**)xpvhv) = xpvhv + 1; xpvhv++; } - xpvhv->xhv_array = 0; + *((XPVHV**)xpvhv) = 0; } /* allocate another arena's worth of struct xpvmg */ @@ -1337,16 +1276,16 @@ S_more_xpvmg(pTHX) XPVMG* xpvmg; XPVMG* xpvmgend; New(719, xpvmg, PERL_ARENA_SIZE/sizeof(XPVMG), XPVMG); - xpvmg->xpv_pv = (char*)PL_xpvmg_arenaroot; + *((XPVMG**)xpvmg) = PL_xpvmg_arenaroot; PL_xpvmg_arenaroot = xpvmg; xpvmgend = &xpvmg[PERL_ARENA_SIZE / sizeof(XPVMG) - 1]; PL_xpvmg_root = ++xpvmg; while (xpvmg < xpvmgend) { - xpvmg->xpv_pv = (char*)(xpvmg + 1); + *((XPVMG**)xpvmg) = xpvmg + 1; xpvmg++; } - xpvmg->xpv_pv = 0; + *((XPVMG**)xpvmg) = 0; } /* allocate another arena's worth of struct xpvgv */ @@ -1357,16 +1296,16 @@ S_more_xpvgv(pTHX) XPVGV* xpvgv; XPVGV* xpvgvend; New(720, xpvgv, PERL_ARENA_SIZE/sizeof(XPVGV), XPVGV); - xpvgv->xpv_pv = (char*)PL_xpvgv_arenaroot; + *((XPVGV**)xpvgv) = PL_xpvgv_arenaroot; PL_xpvgv_arenaroot = xpvgv; xpvgvend = &xpvgv[PERL_ARENA_SIZE / sizeof(XPVGV) - 1]; PL_xpvgv_root = ++xpvgv; while (xpvgv < xpvgvend) { - xpvgv->xpv_pv = (char*)(xpvgv + 1); + *((XPVGV**)xpvgv) = xpvgv + 1; xpvgv++; } - xpvgv->xpv_pv = 0; + *((XPVGV**)xpvgv) = 0; } /* allocate another arena's worth of struct xpvlv */ @@ -1377,16 +1316,16 @@ S_more_xpvlv(pTHX) XPVLV* xpvlv; XPVLV* xpvlvend; New(720, xpvlv, PERL_ARENA_SIZE/sizeof(XPVLV), XPVLV); - xpvlv->xpv_pv = (char*)PL_xpvlv_arenaroot; + *((XPVLV**)xpvlv) = PL_xpvlv_arenaroot; PL_xpvlv_arenaroot = xpvlv; xpvlvend = &xpvlv[PERL_ARENA_SIZE / sizeof(XPVLV) - 1]; PL_xpvlv_root = ++xpvlv; while (xpvlv < xpvlvend) { - xpvlv->xpv_pv = (char*)(xpvlv + 1); + *((XPVLV**)xpvlv) = xpvlv + 1; xpvlv++; } - xpvlv->xpv_pv = 0; + *((XPVLV**)xpvlv) = 0; } /* allocate another arena's worth of struct xpvbm */ @@ -1397,72 +1336,16 @@ S_more_xpvbm(pTHX) XPVBM* xpvbm; XPVBM* xpvbmend; New(721, xpvbm, PERL_ARENA_SIZE/sizeof(XPVBM), XPVBM); - xpvbm->xpv_pv = (char*)PL_xpvbm_arenaroot; + *((XPVBM**)xpvbm) = PL_xpvbm_arenaroot; PL_xpvbm_arenaroot = xpvbm; xpvbmend = &xpvbm[PERL_ARENA_SIZE / sizeof(XPVBM) - 1]; PL_xpvbm_root = ++xpvbm; while (xpvbm < xpvbmend) { - xpvbm->xpv_pv = (char*)(xpvbm + 1); + *((XPVBM**)xpvbm) = xpvbm + 1; xpvbm++; } - xpvbm->xpv_pv = 0; -} - -/* grab a new struct xrv from the free list, allocating more if necessary */ - -STATIC XRV* -S_new_xrv(pTHX) -{ - XRV* xrv; - LOCK_SV_MUTEX; - if (!PL_xrv_root) - S_more_xrv(aTHX); - xrv = PL_xrv_root; - PL_xrv_root = (XRV*)xrv->xrv_rv; - UNLOCK_SV_MUTEX; - return xrv; -} - -/* return a struct xrv to the free list */ - -STATIC void -S_del_xrv(pTHX_ XRV *p) -{ - LOCK_SV_MUTEX; - p->xrv_rv = (SV*)PL_xrv_root; - PL_xrv_root = p; - UNLOCK_SV_MUTEX; -} - -/* grab a new IV body from the free list, allocating more if necessary */ - -STATIC XPVIV* -S_new_xiv(pTHX) -{ - IV* xiv; - LOCK_SV_MUTEX; - if (!PL_xiv_root) - S_more_xiv(aTHX); - xiv = PL_xiv_root; - /* - * See comment in more_xiv() -- RAM. - */ - PL_xiv_root = *(IV**)xiv; - UNLOCK_SV_MUTEX; - return (XPVIV*)((char*)xiv - STRUCT_OFFSET(XPVIV, xiv_iv)); -} - -/* return an IV body to the free list */ - -STATIC void -S_del_xiv(pTHX_ XPVIV *p) -{ - IV* xiv = (IV*)((char*)(p) + STRUCT_OFFSET(XPVIV, xiv_iv)); - LOCK_SV_MUTEX; - *(IV**)xiv = PL_xiv_root; - PL_xiv_root = xiv; - UNLOCK_SV_MUTEX; + *((XPVBM**)xpvbm) = 0; } /* grab a new NV body from the free list, allocating more if necessary */ @@ -1502,7 +1385,7 @@ S_new_xpv(pTHX) if (!PL_xpv_root) S_more_xpv(aTHX); xpv = PL_xpv_root; - PL_xpv_root = (XPV*)xpv->xpv_pv; + PL_xpv_root = *(XPV**)xpv; UNLOCK_SV_MUTEX; return xpv; } @@ -1513,7 +1396,7 @@ STATIC void S_del_xpv(pTHX_ XPV *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpv_root; + *(XPV**)p = PL_xpv_root; PL_xpv_root = p; UNLOCK_SV_MUTEX; } @@ -1528,7 +1411,7 @@ S_new_xpviv(pTHX) if (!PL_xpviv_root) S_more_xpviv(aTHX); xpviv = PL_xpviv_root; - PL_xpviv_root = (XPVIV*)xpviv->xpv_pv; + PL_xpviv_root = *(XPVIV**)xpviv; UNLOCK_SV_MUTEX; return xpviv; } @@ -1539,7 +1422,7 @@ STATIC void S_del_xpviv(pTHX_ XPVIV *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpviv_root; + *(XPVIV**)p = PL_xpviv_root; PL_xpviv_root = p; UNLOCK_SV_MUTEX; } @@ -1554,7 +1437,7 @@ S_new_xpvnv(pTHX) if (!PL_xpvnv_root) S_more_xpvnv(aTHX); xpvnv = PL_xpvnv_root; - PL_xpvnv_root = (XPVNV*)xpvnv->xpv_pv; + PL_xpvnv_root = *(XPVNV**)xpvnv; UNLOCK_SV_MUTEX; return xpvnv; } @@ -1565,7 +1448,7 @@ STATIC void S_del_xpvnv(pTHX_ XPVNV *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpvnv_root; + *(XPVNV**)p = PL_xpvnv_root; PL_xpvnv_root = p; UNLOCK_SV_MUTEX; } @@ -1580,7 +1463,7 @@ S_new_xpvcv(pTHX) if (!PL_xpvcv_root) S_more_xpvcv(aTHX); xpvcv = PL_xpvcv_root; - PL_xpvcv_root = (XPVCV*)xpvcv->xpv_pv; + PL_xpvcv_root = *(XPVCV**)xpvcv; UNLOCK_SV_MUTEX; return xpvcv; } @@ -1591,7 +1474,7 @@ STATIC void S_del_xpvcv(pTHX_ XPVCV *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpvcv_root; + *(XPVCV**)p = PL_xpvcv_root; PL_xpvcv_root = p; UNLOCK_SV_MUTEX; } @@ -1606,7 +1489,7 @@ S_new_xpvav(pTHX) if (!PL_xpvav_root) S_more_xpvav(aTHX); xpvav = PL_xpvav_root; - PL_xpvav_root = (XPVAV*)xpvav->xav_array; + PL_xpvav_root = *(XPVAV**)xpvav; UNLOCK_SV_MUTEX; return xpvav; } @@ -1617,7 +1500,7 @@ STATIC void S_del_xpvav(pTHX_ XPVAV *p) { LOCK_SV_MUTEX; - p->xav_array = (char*)PL_xpvav_root; + *(XPVAV**)p = PL_xpvav_root; PL_xpvav_root = p; UNLOCK_SV_MUTEX; } @@ -1632,7 +1515,7 @@ S_new_xpvhv(pTHX) if (!PL_xpvhv_root) S_more_xpvhv(aTHX); xpvhv = PL_xpvhv_root; - PL_xpvhv_root = (XPVHV*)xpvhv->xhv_array; + PL_xpvhv_root = *(XPVHV**)xpvhv; UNLOCK_SV_MUTEX; return xpvhv; } @@ -1643,7 +1526,7 @@ STATIC void S_del_xpvhv(pTHX_ XPVHV *p) { LOCK_SV_MUTEX; - p->xhv_array = (char*)PL_xpvhv_root; + *(XPVHV**)p = PL_xpvhv_root; PL_xpvhv_root = p; UNLOCK_SV_MUTEX; } @@ -1658,7 +1541,7 @@ S_new_xpvmg(pTHX) if (!PL_xpvmg_root) S_more_xpvmg(aTHX); xpvmg = PL_xpvmg_root; - PL_xpvmg_root = (XPVMG*)xpvmg->xpv_pv; + PL_xpvmg_root = *(XPVMG**)xpvmg; UNLOCK_SV_MUTEX; return xpvmg; } @@ -1669,7 +1552,7 @@ STATIC void S_del_xpvmg(pTHX_ XPVMG *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpvmg_root; + *(XPVMG**)p = PL_xpvmg_root; PL_xpvmg_root = p; UNLOCK_SV_MUTEX; } @@ -1684,7 +1567,7 @@ S_new_xpvgv(pTHX) if (!PL_xpvgv_root) S_more_xpvgv(aTHX); xpvgv = PL_xpvgv_root; - PL_xpvgv_root = (XPVGV*)xpvgv->xpv_pv; + PL_xpvgv_root = *(XPVGV**)xpvgv; UNLOCK_SV_MUTEX; return xpvgv; } @@ -1695,7 +1578,7 @@ STATIC void S_del_xpvgv(pTHX_ XPVGV *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpvgv_root; + *(XPVGV**)p = PL_xpvgv_root; PL_xpvgv_root = p; UNLOCK_SV_MUTEX; } @@ -1710,7 +1593,7 @@ S_new_xpvlv(pTHX) if (!PL_xpvlv_root) S_more_xpvlv(aTHX); xpvlv = PL_xpvlv_root; - PL_xpvlv_root = (XPVLV*)xpvlv->xpv_pv; + PL_xpvlv_root = *(XPVLV**)xpvlv; UNLOCK_SV_MUTEX; return xpvlv; } @@ -1721,7 +1604,7 @@ STATIC void S_del_xpvlv(pTHX_ XPVLV *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpvlv_root; + *(XPVLV**)p = PL_xpvlv_root; PL_xpvlv_root = p; UNLOCK_SV_MUTEX; } @@ -1736,7 +1619,7 @@ S_new_xpvbm(pTHX) if (!PL_xpvbm_root) S_more_xpvbm(aTHX); xpvbm = PL_xpvbm_root; - PL_xpvbm_root = (XPVBM*)xpvbm->xpv_pv; + PL_xpvbm_root = *(XPVBM**)xpvbm; UNLOCK_SV_MUTEX; return xpvbm; } @@ -1747,7 +1630,7 @@ STATIC void S_del_xpvbm(pTHX_ XPVBM *p) { LOCK_SV_MUTEX; - p->xpv_pv = (char*)PL_xpvbm_root; + *(XPVBM**)p = PL_xpvbm_root; PL_xpvbm_root = p; UNLOCK_SV_MUTEX; } @@ -1757,15 +1640,9 @@ S_del_xpvbm(pTHX_ XPVBM *p) #ifdef PURIFY -#define new_XIV() my_safemalloc(sizeof(XPVIV)) -#define del_XIV(p) my_safefree(p) - #define new_XNV() my_safemalloc(sizeof(XPVNV)) #define del_XNV(p) my_safefree(p) -#define new_XRV() my_safemalloc(sizeof(XRV)) -#define del_XRV(p) my_safefree(p) - #define new_XPV() my_safemalloc(sizeof(XPV)) #define del_XPV(p) my_safefree(p) @@ -1798,15 +1675,9 @@ S_del_xpvbm(pTHX_ XPVBM *p) #else /* !PURIFY */ -#define new_XIV() (void*)new_xiv() -#define del_XIV(p) del_xiv((XPVIV*) p) - #define new_XNV() (void*)new_xnv() #define del_XNV(p) del_xnv((XPVNV*) p) -#define new_XRV() (void*)new_xrv() -#define del_XRV(p) del_xrv((XRV*) p) - #define new_XPV() (void*)new_xpv() #define del_XPV(p) del_xpv((XPV *)p) @@ -1887,7 +1758,6 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt) break; case SVt_IV: iv = SvIVX(sv); - del_XIV(SvANY(sv)); if (mt == SVt_NV) mt = SVt_PVNV; else if (mt < SVt_PVIV) @@ -1901,7 +1771,6 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt) break; case SVt_RV: pv = (char*)SvRV(sv); - del_XRV(SvANY(sv)); break; case SVt_PV: pv = SvPVX(sv); @@ -1957,7 +1826,7 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt) case SVt_NULL: Perl_croak(aTHX_ "Can't upgrade to undef"); case SVt_IV: - SvANY(sv) = new_XIV(); + SvANY(sv) = (XPVIV*)((char*)&(sv->sv_u.sv_iv) - STRUCT_OFFSET(XPVIV, xiv_iv)); SvIV_set(sv, iv); break; case SVt_NV: @@ -1965,7 +1834,7 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt) SvNV_set(sv, nv); break; case SVt_RV: - SvANY(sv) = new_XRV(); + SvANY(sv) = &sv->sv_u.sv_rv; SvRV_set(sv, (SV*)pv); break; case SVt_PVHV: @@ -3911,9 +3780,9 @@ Perl_sv_2bool(pTHX_ register SV *sv) if (SvPOKp(sv)) { register XPV* Xpvtmp; if ((Xpvtmp = (XPV*)SvANY(sv)) && - (*Xpvtmp->xpv_pv > '0' || + (*sv->sv_u.sv_pv > '0' || Xpvtmp->xpv_cur > 1 || - (Xpvtmp->xpv_cur && *Xpvtmp->xpv_pv != '0'))) + (Xpvtmp->xpv_cur && *sv->sv_u.sv_pv != '0'))) return 1; else return 0; @@ -5870,6 +5739,15 @@ Perl_sv_replace(pTHX_ register SV *sv, register SV *nsv) #else StructCopy(nsv,sv,SV); #endif + /* Currently could join these into one piece of pointer arithmetic, but + it would be unclear. */ + if(SvTYPE(sv) == SVt_IV) + SvANY(sv) + = (XPVIV*)((char*)&(sv->sv_u.sv_iv) - STRUCT_OFFSET(XPVIV, xiv_iv)); + else if (SvTYPE(sv) == SVt_RV) { + SvANY(sv) = &sv->sv_u.sv_rv; + } + #ifdef PERL_COPY_ON_WRITE if (SvIsCOW_normal(nsv)) { @@ -6084,13 +5962,11 @@ Perl_sv_clear(pTHX_ register SV *sv) case SVt_NULL: break; case SVt_IV: - del_XIV(SvANY(sv)); break; case SVt_NV: del_XNV(SvANY(sv)); break; case SVt_RV: - del_XRV(SvANY(sv)); break; case SVt_PV: del_XPV(SvANY(sv)); @@ -8146,7 +8022,7 @@ Perl_sv_true(pTHX_ register SV *sv) const register XPV* tXpv; if ((tXpv = (XPV*)SvANY(sv)) && (tXpv->xpv_cur > 1 || - (tXpv->xpv_cur && *tXpv->xpv_pv != '0'))) + (tXpv->xpv_cur && *sv->sv_u.sv_pv != '0'))) return 1; else return 0; @@ -10833,7 +10709,7 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param) SvANY(dstr) = NULL; break; case SVt_IV: - SvANY(dstr) = new_XIV(); + SvANY(dstr) = (XPVIV*)((char*)&(dstr->sv_u.sv_iv) - STRUCT_OFFSET(XPVIV, xiv_iv)); SvIV_set(dstr, SvIVX(sstr)); break; case SVt_NV: @@ -10841,7 +10717,7 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param) SvNV_set(dstr, SvNVX(sstr)); break; case SVt_RV: - SvANY(dstr) = new_XRV(); + SvANY(dstr) = &(dstr->sv_u.sv_rv); Perl_rvpv_dup(aTHX_ dstr, sstr, param); break; case SVt_PV: @@ -11040,11 +10916,14 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param) STRLEN i = 0; XPVHV *dxhv = (XPVHV*)SvANY(dstr); XPVHV *sxhv = (XPVHV*)SvANY(sstr); - Newz(0, dxhv->xhv_array, + char *darray; + /* FIXME - surely this doesn't need to be zeroed? */ + Newz(0, darray, PERL_HV_ARRAY_ALLOC_BYTES(dxhv->xhv_max+1), char); + HvARRAY(dstr) = (HE**)darray; while (i <= sxhv->xhv_max) { - ((HE**)dxhv->xhv_array)[i] - = he_dup(((HE**)sxhv->xhv_array)[i], + HvARRAY(dstr)[i] + = he_dup(HvARRAY(sstr)[i], (bool)!!HvSHAREKEYS(sstr), param); ++i; } @@ -11728,12 +11607,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, param->proto_perl = proto_perl; /* arena roots */ - PL_xiv_arenaroot = NULL; - PL_xiv_root = NULL; PL_xnv_arenaroot = NULL; PL_xnv_root = NULL; - PL_xrv_arenaroot = NULL; - PL_xrv_root = NULL; PL_xpv_arenaroot = NULL; PL_xpv_root = NULL; PL_xpviv_arenaroot = NULL; @@ -68,6 +68,13 @@ struct STRUCT_SV { /* struct sv { */ void* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ + union { + IV sv_iv; + UV sv_uv; + SV* sv_rv; /* pointer to another SV */ + char* sv_pv; /* pointer to malloced string */ + SV** sv_array; + } sv_u; #ifdef DEBUG_LEAKING_SCALARS unsigned sv_debug_optype:9; /* the type of OP that allocated us */ unsigned sv_debug_inpad:1; /* was allocated in a pad for an OP */ @@ -81,30 +88,65 @@ struct gv { XPVGV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ + union { + IV sv_iv; + UV sv_uv; + SV* sv_rv; + char* sv_pv; + SV** sv_array; + } sv_u; }; struct cv { XPVCV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ + union { + IV sv_iv; + UV sv_uv; + SV* sv_rv; + char* sv_pv; + SV** sv_array; + } sv_u; }; struct av { XPVAV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ + union { + IV sv_iv; + UV sv_uv; + SV* sv_rv; + char* sv_pv; /* pointer to first array element */ + SV** sv_array; + } sv_u; }; struct hv { XPVHV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ + union { + IV sv_iv; + UV sv_uv; + SV* sv_rv; + char* sv_pv; + SV** sv_array; + } sv_u; }; struct io { XPVIO* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ + union { + IV sv_iv; + UV sv_uv; + SV* sv_rv; + char* sv_pv; + SV** sv_array; + } sv_u; }; /* @@ -232,33 +274,25 @@ perform the upgrade if necessary. See C<svtype>. #define SVpav_REAL 0x40000000 /* free old entries */ #define SVpav_REIFY 0x80000000 /* can become real */ -struct xrv { - SV * xrv_rv; /* pointer to another SV */ -}; - struct xpv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + STRLEN xpv_cur; /* length of sv_pv as a C string */ STRLEN xpv_len; /* allocated size */ }; struct xpviv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + STRLEN xpv_cur; /* length of sv_pv as a C string */ STRLEN xpv_len; /* allocated size */ IV xiv_iv; /* integer value or pv offset */ }; struct xpvuv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + STRLEN xpv_cur; /* length of sv_pv as a C string */ STRLEN xpv_len; /* allocated size */ UV xuv_uv; /* unsigned value or pv offset */ }; struct xpvnv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -266,8 +300,7 @@ struct xpvnv { /* These structure must match the beginning of struct xpvhv in hv.h. */ struct xpvmg { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -276,8 +309,7 @@ struct xpvmg { }; struct xpvlv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -299,8 +331,7 @@ struct xpvlv { }; struct xpvgv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -315,8 +346,7 @@ struct xpvgv { }; struct xpvbm { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -333,8 +363,7 @@ struct xpvbm { typedef U16 cv_flags_t; struct xpvfm { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -359,8 +388,7 @@ struct xpvfm { }; struct xpvio { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xpv_pv as a C string */ + 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 */ @@ -762,9 +790,9 @@ in gv.h: */ #endif #ifdef PERL_DEBUG_COW -#define SvRV(sv) (0 + ((XRV*) SvANY(sv))->xrv_rv) +#define SvRV(sv) (0 + (sv)->sv_u.sv_rv) #else -#define SvRV(sv) ((XRV*) SvANY(sv))->xrv_rv +#define SvRV(sv) ((sv)->sv_u.sv_rv) #endif #define SvRVx(sv) SvRV(sv) @@ -772,10 +800,10 @@ in gv.h: */ #define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv) #define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv) #define SvNVX(sv) (0 + ((XPVNV*) SvANY(sv))->xnv_nv) -#define SvPVX(sv) (0 + ((XPV*) SvANY(sv))->xpv_pv) +#define SvPVX(sv) (0 + (sv)->sv_u.sv_pv) #define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur) #define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len) -#define SvEND(sv) (((XPV*) SvANY(sv))->xpv_pv + ((XPV*)SvANY(sv))->xpv_cur) +#define SvEND(sv) ((sv)->sv_u.sv_pv + ((XPV*)SvANY(sv))->xpv_cur) #ifdef DEBUGGING # ifdef PERL_IN_SV_C @@ -797,10 +825,10 @@ in gv.h: */ #define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv #define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv #define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv -#define SvPVX(sv) ((XPV*) SvANY(sv))->xpv_pv +#define SvPVX(sv) ((sv)->sv_u.sv_pv) #define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur #define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len -#define SvEND(sv) (((XPV*) SvANY(sv))->xpv_pv + ((XPV*)SvANY(sv))->xpv_cur) +#define SvEND(sv) ((sv)->sv_u.sv_pv + ((XPV*)SvANY(sv))->xpv_cur) #ifdef DEBUGGING #define SvMAGIC(sv) (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_magic)) @@ -834,13 +862,13 @@ in gv.h: */ (((XPVNV*)SvANY(sv))->xnv_nv = (val)); } STMT_END #define SvPV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ - (((XPV*) SvANY(sv))->xpv_pv = (val)); } STMT_END + ((sv)->sv_u.sv_pv = (val)); } STMT_END #define SvUV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END #define SvRV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ - (((XRV*)SvANY(sv))->xrv_rv = (val)); } STMT_END + ((sv)->sv_u.sv_rv = (val)); } STMT_END #define SvMAGIC_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ (((XPVMG*)SvANY(sv))->xmg_magic = (val)); } STMT_END @@ -1164,7 +1192,7 @@ Like C<sv_catsv> but doesn't process magic. ? (({XPV *nxpv = (XPV*)SvANY(sv); \ nxpv && \ (nxpv->xpv_cur > 1 || \ - (nxpv->xpv_cur && *nxpv->xpv_pv != '0')); }) \ + (nxpv->xpv_cur && *(sv)->sv_u.sv_pv != '0')); }) \ ? 1 \ : 0) \ : \ @@ -1190,9 +1218,9 @@ Like C<sv_catsv> but doesn't process magic. !sv \ ? 0 \ : SvPOK(sv) \ - ? ((PL_Xpv = (XPV*)SvANY(sv)) && \ + ? ((PL_Xpv = (XPV*)SvANY(PL_Sv = (sv))) && \ (PL_Xpv->xpv_cur > 1 || \ - (PL_Xpv->xpv_cur && *PL_Xpv->xpv_pv != '0')) \ + (PL_Xpv->xpv_cur && *PL_Sv->sv_u.sv_pv != '0')) \ ? 1 \ : 0) \ : \ |