From: Nicholas Clark Date: Thu, 22 Mar 2007 14:00:14 +0000 (+0000) Subject: Re-order the flags values for struct refcounted_he to allow the X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=44ebaf214d875023892e1fcbaf9e864b01c5c7e0;p=p5sagit%2Fp5-mst-13.2.git Re-order the flags values for struct refcounted_he to allow the possibility of storing 2 futher types. Add a void * to the union as it won't increase the size, but may become useful. p4raw-id: //depot/perl@30683 --- diff --git a/hv.c b/hv.c index 4831ccd..4266e8b 100644 --- a/hv.c +++ b/hv.c @@ -2581,11 +2581,13 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he) value = &PL_sv_placeholder; break; case HVrhek_IV: - value = (he->refcounted_he_data[0] & HVrhek_UV) - ? newSVuv(he->refcounted_he_val.refcounted_he_u_iv) - : newSViv(he->refcounted_he_val.refcounted_he_u_uv); + value = newSViv(he->refcounted_he_val.refcounted_he_u_iv); + break; + case HVrhek_UV: + value = newSVuv(he->refcounted_he_val.refcounted_he_u_uv); break; case HVrhek_PV: + case HVrhek_PV_UTF8: /* Create a string SV that directly points to the bytes in our structure. */ value = newSV_type(SVt_PV); @@ -2595,7 +2597,7 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he) SvLEN_set(value, 0); SvPOK_on(value); SvREADONLY_on(value); - if (he->refcounted_he_data[0] & HVrhek_UTF8) + if ((he->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV_UTF8) SvUTF8_on(value); break; default: @@ -2605,14 +2607,6 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he) return value; } -#ifdef USE_ITHREADS -/* A big expression to find the key offset */ -#define REF_HE_KEY(chain) \ - ((((chain->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV) \ - ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0) \ - + 1 + chain->refcounted_he_data) -#endif - /* =for apidoc refcounted_he_chain_2hv @@ -2821,7 +2815,6 @@ Perl_refcounted_he_new(pTHX_ struct refcounted_he *const parent, value_len = 0; key_offset = 1; } - flags = value_type; #ifdef USE_ITHREADS he = (struct refcounted_he*) @@ -2840,17 +2833,19 @@ Perl_refcounted_he_new(pTHX_ struct refcounted_he *const parent, if (value_type == HVrhek_PV) { Copy(value_p, he->refcounted_he_data + 1, value_len + 1, char); he->refcounted_he_val.refcounted_he_u_len = value_len; - if (SvUTF8(value)) { - flags |= HVrhek_UTF8; - } + /* Do it this way so that the SvUTF8() test is after the SvPV, in case + the value is overloaded, and doesn't yet have the UTF-8flag set. */ + if (SvUTF8(value)) + value_type = HVrhek_PV_UTF8; } else if (value_type == HVrhek_IV) { if (SvUOK(value)) { he->refcounted_he_val.refcounted_he_u_uv = SvUVX(value); - flags |= HVrhek_UV; + value_type = HVrhek_UV; } else { he->refcounted_he_val.refcounted_he_u_iv = SvIVX(value); } } + flags = value_type; if (is_utf8) { /* Hash keys are always stored normalised to (yes) ISO-8859-1. diff --git a/hv.h b/hv.h index 6e19c84..d6a0361 100644 --- a/hv.h +++ b/hv.h @@ -390,6 +390,8 @@ C. between threads (because it hangs from OPs, which are shared), hence the alternate definition and mutex. */ +struct refcounted_he; + #ifdef PERL_CORE /* Gosh. This really isn't a good name any longer. */ @@ -406,6 +408,7 @@ struct refcounted_he { IV refcounted_he_u_iv; UV refcounted_he_u_uv; STRLEN refcounted_he_u_len; + void *refcounted_he_u_ptr; /* Might be useful in future */ } refcounted_he_val; /* First byte is flags. Then NUL-terminated value. Then for ithreads, non-NUL terminated key. */ @@ -414,12 +417,22 @@ struct refcounted_he { /* 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. */ +#define HVrhek_delete 0x10 /* Value is placeholder - signifies delete. */ +#define HVrhek_IV 0x20 /* Value is IV. */ +#define HVrhek_UV 0x30 /* Value is UV. */ +#define HVrhek_PV 0x40 /* Value is a (byte) string. */ +#define HVrhek_PV_UTF8 0x50 /* Value is a (utf8) string. */ +/* Two spare. As these have to live in the optree, you can't store anything + interpreter specific, such as SVs. :-( */ +#define HVrhek_typemask 0x70 + +#ifdef USE_ITHREADS +/* A big expression to find the key offset */ +#define REF_HE_KEY(chain) \ + ((((chain->refcounted_he_data[0] & 0x60) == 0x40) \ + ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0) \ + + 1 + chain->refcounted_he_data) +#endif # ifdef USE_ITHREADS # define HINTS_REFCNT_LOCK MUTEX_LOCK(&PL_hints_mutex)