summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/XS/APItest/APItest.xs2
-rw-r--r--hv.c12
-rw-r--r--hv.h9
-rw-r--r--perl.c2
4 files changed, 14 insertions, 11 deletions
diff --git a/ext/XS/APItest/APItest.xs b/ext/XS/APItest/APItest.xs
index c2a647800a..c8391c6bf2 100644
--- a/ext/XS/APItest/APItest.xs
+++ b/ext/XS/APItest/APItest.xs
@@ -86,7 +86,7 @@ test_freeent(freeent_function *f) {
test_scalar = newSV(0);
SvREFCNT_inc(test_scalar);
- victim->hent_val = test_scalar;
+ HeVAL(victim) = test_scalar;
/* Need this little game else we free the temps on the return stack. */
results[0] = SvREFCNT(test_scalar);
diff --git a/hv.c b/hv.c
index c458f561ff..0ab2558de9 100644
--- a/hv.c
+++ b/hv.c
@@ -2279,8 +2279,8 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash)
assert (he->shared_he_he.hent_hek == hek);
LOCK_STRTAB_MUTEX;
- if (he->shared_he_he.hent_val - 1) {
- --he->shared_he_he.hent_val;
+ if (he->shared_he_he.he_valu.hent_refcount - 1) {
+ --he->shared_he_he.he_valu.hent_refcount;
UNLOCK_STRTAB_MUTEX;
return;
}
@@ -2299,7 +2299,7 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash)
k_flags |= HVhek_WASUTF8 | HVhek_FREEKEY;
}
- /* what follows is the moral equivalent of:
+ /* what follows was the moral equivalent of:
if ((Svp = hv_fetch(PL_strtab, tmpsv, FALSE, hash))) {
if (--*Svp == Nullsv)
hv_delete(PL_strtab, str, len, G_DISCARD, hash);
@@ -2333,7 +2333,7 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash)
}
if (found) {
- if (--HeVAL(entry) == Nullsv) {
+ if (--he->shared_he_he.he_valu.hent_refcount == 0) {
*oentry = HeNEXT(entry);
if (!*first) {
/* There are now no entries in our slot. */
@@ -2449,7 +2449,7 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
/* Still "point" to the HEK, so that other code need not know what
we're up to. */
HeKEY_hek(entry) = hek;
- HeVAL(entry) = Nullsv;
+ entry->he_valu.hent_refcount = 0;
HeNEXT(entry) = next;
*head = entry;
@@ -2461,7 +2461,7 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
}
}
- ++HeVAL(entry); /* use value slot as REFCNT */
+ ++entry->he_valu.hent_refcount;
UNLOCK_STRTAB_MUTEX;
if (flags & HVhek_FREEKEY)
diff --git a/hv.h b/hv.h
index d0ac0e8054..fd0cf2eda2 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 */
@@ -291,7 +294,7 @@ C<SV*>.
#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) : \
@@ -372,7 +375,7 @@ C<SV*>.
(++(((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)
/*
diff --git a/perl.c b/perl.c
index 82960f3a37..e9f7795892 100644
--- a/perl.c
+++ b/perl.c
@@ -1100,7 +1100,7 @@ perl_destruct(pTHXx)
HE * const next = HeNEXT(hent);
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
"Unbalanced string table refcount: (%ld) for \"%s\"",
- (long)(HeVAL(hent) - Nullsv), HeKEY(hent));
+ (long)hent->he_valu.hent_refcount, HeKEY(hent));
Safefree(hent);
hent = next;
}