X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.h;h=fc5bcdeb9b5ca68bfe8f3e42006717fcbcffbf0a;hb=a4d60858fc3c717ec83cbdceb029a69fc535e3f8;hp=ddbdd80b065c898b8e5d26db575e759a8b5bd7d1;hpb=199f3245d0efbd4bc138ab358c5f5889c79d7083;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.h b/hv.h index ddbdd80..fc5bcde 100644 --- a/hv.h +++ b/hv.h @@ -14,6 +14,9 @@ typedef struct hek HEK; /* entry in hash value chain */ struct he { + /* Keep hent_next first in this structure, because sv_free_arenas take + advantage of this to share code between the he arenas and the SV + body arenas */ HE *hent_next; /* next entry in chain */ HEK *hent_hek; /* hash key */ SV *hent_val; /* scalar value that was hashed */ @@ -29,12 +32,16 @@ struct hek { is UTF-8 */ }; +struct shared_he { + struct he shared_he_he; + struct hek shared_he_hek; +}; /* Subject to change. Don't access this directly. */ struct xpvhv_aux { - char *xhv_name; /* name, if a symbol table */ + HEK *xhv_name; /* name, if a symbol table */ HE *xhv_eiter; /* current entry of iterator */ I32 xhv_riter; /* current root of iterator */ }; @@ -42,26 +49,19 @@ 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. */ }; -#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 0 typedef struct xpvhv xpvhv_allocated; @@ -70,15 +70,10 @@ 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 */ } xpvhv_allocated; @@ -213,22 +208,27 @@ C. #define Nullhv Null(HV*) -#define HvARRAY(hv) (*(HE***)&((hv)->sv_u.sv_array)) +#define HvARRAY(hv) (*(HE***)&((hv)->sv_u.svu_array)) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill #define HvMAX(hv) ((XPVHV*) SvANY(hv))->xhv_max +/* This quite intentionally does no flag checking first. That's your + responsibility. */ +#define HvAUX(hv) ((struct xpvhv_aux*)&(HvARRAY(hv)[HvMAX(hv)+1])) #define HvRITER(hv) (*Perl_hv_riter_p(aTHX_ (HV*)(hv))) #define HvEITER(hv) (*Perl_hv_eiter_p(aTHX_ (HV*)(hv))) #define HvRITER_set(hv,r) Perl_hv_riter_set(aTHX_ (HV*)(hv), r) #define HvEITER_set(hv,e) Perl_hv_eiter_set(aTHX_ (HV*)(hv), e) -#define HvRITER_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - ((struct xpvhv_aux*)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_riter : -1) -#define HvEITER_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - ((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_eiter : 0) -#define HvNAME(hv) (*Perl_hv_name_p(aTHX_ (HV*)hv)) +#define HvRITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_riter : -1) +#define HvEITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_eiter : 0) +#define HvNAME(hv) HvNAME_get(hv) /* FIXME - all of these should use a UTF8 aware API, which should also involve getting the length. */ -#define HvNAME_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - ((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name : 0) +/* This macro may go away without notice. */ +#define HvNAME_HEK(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_name : 0) +#define HvNAME_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \ + ? HEK_KEY(HvAUX(hv)->xhv_name) : 0) +#define HvNAMELEN_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \ + ? HEK_LEN(HvAUX(hv)->xhv_name) : 0) /* the number of keys (including any placeholers) */ #define XHvTOTALKEYS(xhv) ((xhv)->xhv_keys) @@ -367,6 +367,13 @@ C. #define Perl_sharepvn(sv, len, hash) HEK_KEY(share_hek(sv, len, hash)) #define sharepvn(sv, len, hash) Perl_sharepvn(sv, len, hash) +#define share_hek_hek(hek) \ + (++(((struct shared_he *)(((char *)hek) \ + - STRUCT_OFFSET(struct shared_he, \ + shared_he_hek))) \ + ->shared_he_he.hent_val), \ + hek) + /* * Local variables: * c-indentation-style: bsd