From: Nicholas Clark Date: Mon, 30 Jan 2006 12:59:12 +0000 (+0000) Subject: Use a union for storing the shared hash key reference count, rather X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=de61663159118b735969bec9539d9251323990fa;p=p5sagit%2Fp5-mst-13.2.git Use a union for storing the shared hash key reference count, rather than messy pointer hacks. p4raw-id: //depot/perl@27000 --- diff --git a/ext/XS/APItest/APItest.xs b/ext/XS/APItest/APItest.xs index c2a6478..c8391c6 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 c458f56..0ab2558 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 d0ac0e8..fd0cf2e 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. #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. (++(((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 82960f3..e9f7795 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; }