diff options
author | Nicholas Clark <nick@ccl4.org> | 2007-03-22 14:00:14 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2007-03-22 14:00:14 +0000 |
commit | 44ebaf214d875023892e1fcbaf9e864b01c5c7e0 (patch) | |
tree | 080663eb85bb8c6cae7b687a418c652bffc6ef75 | |
parent | c24033b9cf73473ddef37d0a45d2c56f24f44fc9 (diff) | |
download | perl-44ebaf214d875023892e1fcbaf9e864b01c5c7e0.tar.gz |
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
-rw-r--r-- | hv.c | 29 | ||||
-rw-r--r-- | hv.h | 25 |
2 files changed, 31 insertions, 23 deletions
@@ -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. @@ -390,6 +390,8 @@ C<SV*>. 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) |