summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-10-16 18:06:44 +0000
committerNicholas Clark <nick@ccl4.org>2021-10-20 15:34:23 +0000
commit33042aafe7427f88db58e555390c82dd25ef9a28 (patch)
tree56a3df0e0d6d3d27ccdabb89941863b1d942003b /hv.c
parent7c4cc0343c223680358a798ea6826c8c3a710db3 (diff)
downloadperl-33042aafe7427f88db58e555390c82dd25ef9a28.tar.gz
Fix the build and tests when NODEFAULT_SHAREKEYS is defined
Defining this macro causes newHV() to create hashes without shared hash key scalars. The default is that hashes are created with shared hash keys.
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/hv.c b/hv.c
index 06fe493f3f..c9f2ef89d6 100644
--- a/hv.c
+++ b/hv.c
@@ -640,6 +640,9 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
PERL_HASH(hash, key, klen);
masked_flags = (flags & HVhek_MASK);
+ if (!HvSHAREKEYS(hv)) {
+ masked_flags |= HVhek_UNSHARED;
+ }
#ifdef DYNAMIC_ENV_FETCH
if (!HvARRAY(hv)) entry = NULL;
@@ -1594,8 +1597,12 @@ Perl_newHVhv(pTHX_ HV *ohv)
ents = (HE**)a;
if (shared) {
+#ifdef NODEFAULT_SHAREKEYS
+ HvSHAREKEYS_on(hv);
+#else
/* Shared is the default - it should have been set by newHV(). */
assert(HvSHAREKEYS(hv));
+#endif
}
else {
HvSHAREKEYS_off(hv);
@@ -1732,10 +1739,14 @@ S_hv_free_ent_ret(pTHX_ HV *hv, HE *entry)
SvREFCNT_dec(HeKEY_sv(entry));
Safefree(HeKEY_hek(entry));
}
- else if (HvSHAREKEYS(hv))
+ else if (HvSHAREKEYS(hv)) {
+ assert((HEK_FLAGS(HeKEY_hek(entry)) & HVhek_UNSHARED) == 0);
unshare_hek(HeKEY_hek(entry));
- else
+ }
+ else {
+ assert((HEK_FLAGS(HeKEY_hek(entry)) & HVhek_UNSHARED) == HVhek_UNSHARED);
Safefree(HeKEY_hek(entry));
+ }
del_HE(entry);
return val;
}
@@ -2918,6 +2929,7 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash)
struct shared_he *he = NULL;
if (hek) {
+ assert((HEK_FLAGS(hek) & HVhek_UNSHARED) == 0);
/* Find the shared he which is just before us in memory. */
he = (struct shared_he *)(((char *)hek)
- STRUCT_OFFSET(struct shared_he,
@@ -3224,6 +3236,11 @@ Perl_refcounted_he_chain_2hv(pTHX_ const struct refcounted_he *chain, U32 flags)
and call ksplit. But for now we'll make a potentially inefficient
hash with only 8 entries in its array. */
hv = newHV();
+#ifdef NODEFAULT_SHAREKEYS
+ /* We share keys in the COP, so it's much easier to keep sharing keys in
+ the hash we build from it. */
+ HvSHAREKEYS_on(hv);
+#endif
max = HvMAX(hv);
if (!HvARRAY(hv)) {
char *array;