Fixes to bugs introduced by PL_stashcache
Artur Bergman [Mon, 14 Apr 2003 21:15:00 +0000 (21:15 +0000)]
A) Follow suggestion by Benjamin Goldberg to use hv_delete
instead of hv_delete_ent to avoid creating a temporary SV
B) Don't increment the refcount, sneak it into an IV instead
C) When a GP is a deleted that contains a stash, remove the
corresponding entry since hv might be in use in other places.
D) Note that no test cases test the deletion of packages to catch
this bug.

p4raw-id: //depot/perl@19212

gv.c
hv.c
pp_hot.c

diff --git a/gv.c b/gv.c
index 7d21f02..0788dd6 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1240,6 +1240,8 @@ Perl_gp_free(pTHX_ GV *gv)
 
     SvREFCNT_dec(gp->gp_sv);
     SvREFCNT_dec(gp->gp_av);
+    if(gp->gp_hv && PL_stashcache)
+        hv_delete(PL_stashcache, HvNAME(gp->gp_hv), strlen(HvNAME(gp->gp_hv)), G_DISCARD);
     SvREFCNT_dec(gp->gp_hv);
     SvREFCNT_dec(gp->gp_io);
     SvREFCNT_dec(gp->gp_cv);
diff --git a/hv.c b/hv.c
index 4300e36..d1f7682 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1739,8 +1739,8 @@ Perl_hv_undef(pTHX_ HV *hv)
     hfreeentries(hv);
     Safefree(xhv->xhv_array /* HvARRAY(hv) */);
     if (HvNAME(hv)) {
-        if(PL_stashcache) 
-            hv_delete_ent(PL_stashcache, sv_2mortal(newSVpv(HvNAME(hv),0)), G_DISCARD, 0);
+        if(PL_stashcache)
+           hv_delete(PL_stashcache, HvNAME(hv), strlen(HvNAME(hv)), G_DISCARD);
        Safefree(HvNAME(hv));
        HvNAME(hv) = 0;
     }
index 553f001..a8b9dff 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2928,9 +2928,10 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
        packname = Nullch;
 
         if(SvOK(sv) && (packname = SvPV(sv, packlen))) {
-          HE* he = hv_fetch_ent(PL_stashcache, sv, 0, 0);
+          HE* he;
+         he = hv_fetch_ent(PL_stashcache, sv, 0, 0);
           if (he) { 
-            stash = (HV*)HeVAL(he);
+            stash = (HV*)SvIV(HeVAL(he));
             goto fetch;
           }
         }
@@ -2956,10 +2957,9 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
            if (!stash)
                packsv = sv;
             else {
-              SvREFCNT_inc((SV*)stash);
-              if(!hv_store(PL_stashcache, packname, packlen, (SV*)stash, 0))
-                SvREFCNT_dec((SV*)stash);
-            }
+               SV* ref = newSViv((IV)stash);
+               hv_store(PL_stashcache, packname, packlen, ref, 0);
+           }
            goto fetch;
        }
        /* it _is_ a filehandle name -- replace with a reference */