X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.h;h=9e31335228c96dfd1cb6fc4d226f4f363f21bae8;hb=903fe02ab005d9a6f5d2870ed93bddff5a74bffb;hp=1ec5d5613bb1c957ff6e3c07be906c9222cd1eec;hpb=43e6e717d18ccf9c351f44370ef56abe09dc1cc4;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.h b/hv.h index 1ec5d56..9e31335 100644 --- a/hv.h +++ b/hv.h @@ -15,7 +15,10 @@ struct he { body arenas */ HE *hent_next; /* next entry in chain */ HEK *hent_hek; /* hash key */ - SV *hent_val; /* scalar value that was hashed */ + union { + SV *hent_val; /* scalar value that was hashed */ + Size_t hent_refcount; /* references for this shared hash key */ + } he_valu; }; /* hash key -- defined separately for use as shared pointer */ @@ -38,6 +41,7 @@ struct shared_he { */ struct xpvhv_aux { HEK *xhv_name; /* name, if a symbol table */ + AV *xhv_backreferences; /* back references for weak references */ HE *xhv_eiter; /* current entry of iterator */ I32 xhv_riter; /* current root of iterator */ }; @@ -45,15 +49,23 @@ struct xpvhv_aux { /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xhv_fill; /* how full xhv_array currently is */ STRLEN xhv_max; /* subscript of last element of xhv_array */ union { IV xivu_iv; /* integer value or pv offset */ UV xivu_uv; void * xivu_p1; + I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; - MAGIC* xmg_magic; /* magic for scalar array */ + union { + MAGIC* xmg_magic; /* linked list of magicalness */ + HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */ + } xmg_u; HV* xmg_stash; /* class package */ }; @@ -69,8 +81,13 @@ typedef struct { IV xivu_iv; /* integer value or pv offset */ UV xivu_uv; void * xivu_p1; + I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; - MAGIC* xmg_magic; /* magic for scalar array */ + union { + MAGIC* xmg_magic; /* linked list of magicalness */ + HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */ + } xmg_u; HV* xmg_stash; /* class package */ } xpvhv_allocated; #endif @@ -82,7 +99,7 @@ typedef struct { /* The use of a temporary pointer and the casting games * is needed to serve the dual purposes of * (a) the hashed data being interpreted as "unsigned char" (new since 5.8, - * a "char" can be either signed or signed, depending on the compiler) + * a "char" can be either signed or unsigned, depending on the compiler) * (b) catering for old code that uses a "char" * * The "hash seed" feature was added in Perl 5.8.1 to perturb the results @@ -103,7 +120,7 @@ typedef struct { #endif #define PERL_HASH(hash,str,len) \ STMT_START { \ - register const char *s_PeRlHaSh_tmp = str; \ + register const char * const s_PeRlHaSh_tmp = str; \ register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \ register I32 i_PeRlHaSh = len; \ register U32 hash_PeRlHaSh = PERL_HASH_SEED; \ @@ -121,7 +138,7 @@ typedef struct { #ifdef PERL_HASH_INTERNAL_ACCESS #define PERL_HASH_INTERNAL(hash,str,len) \ STMT_START { \ - register const char *s_PeRlHaSh_tmp = str; \ + register const char * const s_PeRlHaSh_tmp = str; \ register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \ register I32 i_PeRlHaSh = len; \ register U32 hash_PeRlHaSh = PL_rehash_seed; \ @@ -185,7 +202,7 @@ the length of hash keys. This is very similar to the C macro described elsewhere in this document. =for apidoc Am|SV*|HeSVKEY|HE* he -Returns the key as an C, or C if the hash entry does not +Returns the key as an C, or C if the hash entry does not contain an C key. =for apidoc Am|SV*|HeSVKEY_force|HE* he @@ -266,19 +283,6 @@ C. #define HvREHASH_on(hv) (SvFLAGS(hv) |= SVphv_REHASH) #define HvREHASH_off(hv) (SvFLAGS(hv) &= ~SVphv_REHASH) -/* Maybe amagical: */ -/* #define HV_AMAGICmb(hv) (SvFLAGS(hv) & (SVpgv_badAM | SVpgv_AM)) */ - -#define HV_AMAGIC(hv) (SvFLAGS(hv) & SVpgv_AM) -#define HV_AMAGIC_on(hv) (SvFLAGS(hv) |= SVpgv_AM) -#define HV_AMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_AM) - -/* -#define HV_AMAGICbad(hv) (SvFLAGS(hv) & SVpgv_badAM) -#define HV_badAMAGIC_on(hv) (SvFLAGS(hv) |= SVpgv_badAM) -#define HV_badAMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_badAM) -*/ - #define Nullhe Null(HE*) #define HeNEXT(he) (he)->hent_next #define HeKEY_hek(he) (he)->hent_hek @@ -290,16 +294,16 @@ C. #define HeKREHASH(he) HEK_REHASH(HeKEY_hek(he)) #define HeKLEN_UTF8(he) (HeKUTF8(he) ? -HeKLEN(he) : HeKLEN(he)) #define HeKFLAGS(he) HEK_FLAGS(HeKEY_hek(he)) -#define HeVAL(he) (he)->hent_val +#define HeVAL(he) (he)->he_valu.hent_val #define HeHASH(he) HEK_HASH(HeKEY_hek(he)) #define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \ SvPV(HeKEY_sv(he),lp) : \ (((lp = HeKLEN(he)) >= 0) ? \ - HeKEY(he) : Nullch)) + HeKEY(he) : NULL)) #define HeSVKEY(he) ((HeKEY(he) && \ HeKLEN(he) == HEf_SVKEY) ? \ - HeKEY_sv(he) : Nullsv) + HeKEY_sv(he) : NULL) #define HeSVKEY_force(he) (HeKEY(he) ? \ ((HeKLEN(he) == HEf_SVKEY) ? \ @@ -360,6 +364,9 @@ C. /* Flags for hv_iternext_flags. */ #define HV_ITERNEXT_WANTPLACEHOLDERS 0x01 /* Don't skip placeholders. */ +#define hv_iternext(hv) hv_iternext_flags(hv, 0) +#define hv_magic(hv, gv, how) sv_magic((SV*)(hv), (SV*)(gv), how, NULL, 0) + /* available as a function in hv.c */ #define Perl_sharepvn(sv, len, hash) HEK_KEY(share_hek(sv, len, hash)) #define sharepvn(sv, len, hash) Perl_sharepvn(sv, len, hash) @@ -368,9 +375,63 @@ C. (++(((struct shared_he *)(((char *)hek) \ - STRUCT_OFFSET(struct shared_he, \ shared_he_hek))) \ - ->shared_he_he.hent_val), \ + ->shared_he_he.he_valu.hent_refcount), \ hek) +/* This refcounted he structure is used for storing the hints used for lexical + pragmas. Without threads, it's basically struct he + refcount. + With threads, life gets more complex as the structure needs to be shared + between threads (because it hangs from OPs, which are shared), hence the + alternate definition and mutex. */ + +#ifdef PERL_CORE + +/* Gosh. This really isn't a good name any longer. */ +struct refcounted_he { + struct refcounted_he *refcounted_he_next; /* next entry in chain */ +#ifdef USE_ITHREADS + U32 refcounted_he_hash; + U32 refcounted_he_keylen; +#else + HEK *refcounted_he_hek; /* hint key */ +#endif + U32 refcounted_he_refcnt; /* reference count */ + union { + IV refcounted_he_u_iv; + UV refcounted_he_u_uv; + STRLEN refcounted_he_u_len; + } refcounted_he_val; + /* First byte is flags. Then NUL-terminated value. Then for ithreads, + non-NUL terminated key. */ + char refcounted_he_data[1]; +}; + +/* Flag bits are HVhek_UTF8, HVhek_WASUTF8, then */ +#define HVrhek_undef 0x00 /* Value is undef. */ +#define HVrhek_PV 0x10 /* Value is a string. */ +#define HVrhek_IV 0x20 /* Value is IV/UV. */ +#define HVrhek_delete 0x30 /* Value is placeholder - signifies delete. */ +#define HVrhek_typemask 0x30 +#define HVrhek_UTF8 0x40 /* string value is utf8. */ +#define HVrhek_UV 0x40 /* integer value is UV. */ + +# ifdef USE_ITHREADS +# define HINTS_REFCNT_LOCK MUTEX_LOCK(&PL_hints_mutex) +# define HINTS_REFCNT_UNLOCK MUTEX_UNLOCK(&PL_hints_mutex) +# else +# define HINTS_REFCNT_LOCK NOOP +# define HINTS_REFCNT_UNLOCK NOOP +# endif +#endif + +#ifdef USE_ITHREADS +# define HINTS_REFCNT_INIT MUTEX_INIT(&PL_hints_mutex) +# define HINTS_REFCNT_TERM MUTEX_DESTROY(&PL_hints_mutex) +#else +# define HINTS_REFCNT_INIT NOOP +# define HINTS_REFCNT_TERM NOOP +#endif + /* * Local variables: * c-indentation-style: bsd