From: Nicholas Clark Date: Tue, 2 May 2006 22:19:56 +0000 (+0000) Subject: Add a new hash key flag HVhek_UNSHARED, to mark all unshared hash keys. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=45e3480058a48be9675e10a3f8cf34c1b211df0e;p=p5sagit%2Fp5-mst-13.2.git Add a new hash key flag HVhek_UNSHARED, to mark all unshared hash keys. Otherwise Perl_newSVhek(), called by Perl_hv_iterkeysv(), naively assumes that it can share any hash key directly. p4raw-id: //depot/perl@28069 --- diff --git a/hv.c b/hv.c index a5336c6..39fadfc 100644 --- a/hv.c +++ b/hv.c @@ -104,7 +104,7 @@ S_save_hek_flags(const char *str, I32 len, U32 hash, int flags) HEK_KEY(hek)[len] = 0; HEK_LEN(hek) = len; HEK_HASH(hek) = hash; - HEK_FLAGS(hek) = (unsigned char)flags_masked; + HEK_FLAGS(hek) = (unsigned char)flags_masked | HVhek_UNSHARED; if (flags & HVhek_FREEKEY) Safefree(str); diff --git a/hv.h b/hv.h index 9e31335..bd157f8 100644 --- a/hv.h +++ b/hv.h @@ -323,6 +323,7 @@ C. #define HVhek_UTF8 0x01 /* Key is utf8 encoded. */ #define HVhek_WASUTF8 0x02 /* Key is bytes here, but was supplied as utf8. */ #define HVhek_REHASH 0x04 /* This key is in an hv using a custom HASH . */ +#define HVhek_UNSHARED 0x08 /* This key isn't a shared hash key. */ #define HVhek_FREEKEY 0x100 /* Internal flag to say key is malloc()ed. */ #define HVhek_PLACEHOLD 0x200 /* Internal flag to create placeholder. * (may change, but Storable is a core module) */ @@ -333,10 +334,11 @@ C. into all keys as hv_iternext has no access to the hash flags. At this point Storable's tests get upset, because sometimes hashes are "keyed" and sometimes not, depending on the order of data insertion, and whether - it triggered rehashing. So currently HVhek_REHAS is exempt. + it triggered rehashing. So currently HVhek_REHASH is exempt. + Similarly UNSHARED */ -#define HVhek_ENABLEHVKFLAGS (HVhek_MASK - HVhek_REHASH) +#define HVhek_ENABLEHVKFLAGS (HVhek_MASK & ~(HVhek_REHASH|HVhek_UNSHARED)) #define HEK_UTF8(hek) (HEK_FLAGS(hek) & HVhek_UTF8) #define HEK_UTF8_on(hek) (HEK_FLAGS(hek) |= HVhek_UTF8) diff --git a/sv.c b/sv.c index 1fb948b..e0e47e4 100644 --- a/sv.c +++ b/sv.c @@ -6981,12 +6981,15 @@ Perl_newSVhek(pTHX_ const HEK *hek) SvUTF8_on (sv); Safefree (as_utf8); /* bytes_to_utf8() allocates a new string */ return sv; - } else if (flags & HVhek_REHASH) { + } else if (flags & (HVhek_REHASH|HVhek_UNSHARED)) { /* We don't have a pointer to the hv, so we have to replicate the flag into every HEK. This hv is using custom a hasing algorithm. Hence we can't return a shared string scalar, as that would contain the (wrong) hash value, and might get passed - into an hv routine with a regular hash */ + into an hv routine with a regular hash. + Similarly, a hash that isn't using shared hash keys has to have + the flag in every key so that we know not to try to call + share_hek_kek on it. */ SV * const sv = newSVpvn (HEK_KEY(hek), HEK_LEN(hek)); if (HEK_UTF8(hek))