8c34e50dc slowed down detruction with no DESTROY
authorFather Chrysostomos <sprout@cpan.org>
Sat, 17 Nov 2012 18:49:11 +0000 (10:49 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 17 Nov 2012 21:49:08 +0000 (13:49 -0800)
I changed it to cache the DESTROY method in SvSTASH(stash), instead
of amagic tables, for the sake of speed.  But I made no distinction
between ‘no cache’ and ‘no DESTROY method’.  So classes with no
DESTROY method became as slow as perl 5.6.

To solve that, I’m using an adjusted pointer (following the example
of warnings.h) to mean ‘intentionally blank’.

I also fixed two instances of the DESTROY cache not being updated,
introduced by that commit.

mro.c
sv.c

index 2d1d887..be2038f 100644 (file)
--- a/mro.c
+++ b/mro.c
@@ -578,6 +578,7 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash)
                 revmeta->cache_gen++;
             if(revmeta->mro_nextmethod)
                 hv_clear(revmeta->mro_nextmethod);
+           if (!SvOBJECT(revstash)) SvSTASH(revstash) = NULL;
 
            (void)
              hv_store(
@@ -1356,6 +1357,7 @@ Perl_mro_method_changed_in(pTHX_ HV *stash)
             mrometa->cache_gen++;
             if(mrometa->mro_nextmethod)
                 hv_clear(mrometa->mro_nextmethod);
+            if (!SvOBJECT(revstash)) SvSTASH(revstash) = NULL;
         }
     }
 
diff --git a/sv.c b/sv.c
index b034f4e..e31301d 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6338,12 +6338,12 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) {
            if (!destructor) {
                GV * const gv =
                    gv_fetchmeth_autoload(stash, "DESTROY", 7, 0);
-               if (gv && (destructor = GvCV(gv))) {
-                   if (!SvOBJECT(stash))
-                       SvSTASH(stash) = (HV *)destructor;
-               }
+               if (gv) destructor = GvCV(gv);
+               if (!SvOBJECT(stash))
+                   SvSTASH(stash) =
+                       destructor ? (HV *)destructor : ((HV *)0)+1;
            }
-           if (destructor
+           if (destructor && destructor != ((CV *)0)+1
                /* A constant subroutine can have no side effects, so
                   don't bother calling it.  */
                && !CvCONST(destructor)
@@ -12000,7 +12000,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                    SvOURSTASH_set(dstr, hv_dup_inc(SvOURSTASH(dstr), param));
                } else if (SvMAGIC(dstr))
                    SvMAGIC_set(dstr, mg_dup(SvMAGIC(dstr), param));
-               if (SvSTASH(dstr))
+               if (SvOBJECT(dstr) && SvSTASH(dstr))
                    SvSTASH_set(dstr, hv_dup_inc(SvSTASH(dstr), param));
            }