diff options
author | Steve Hay <steve.m.hay@googlemail.com> | 2016-04-08 22:47:20 +0100 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2016-04-08 22:47:20 +0100 |
commit | 2ae6b218aa4e7c8d9566ef6a64f131d1b56581c4 (patch) | |
tree | d05351efad981032baae8110ca0d5fcc8b3f528b | |
parent | 59e4a1347f3bc090b98a30385cf375565b6a924f (diff) | |
download | perl-2ae6b218aa4e7c8d9566ef6a64f131d1b56581c4.tar.gz |
Revert "[perl #126410] keep the DESTROY cache in mro_meta"
This reverts commit 971809a61a634661b679cfedb722bf989b33d0d5.
-rw-r--r-- | ext/B/t/sv_stash.t | 1 | ||||
-rw-r--r-- | hv.h | 1 | ||||
-rw-r--r-- | mro_core.c | 14 | ||||
-rw-r--r-- | sv.c | 34 |
4 files changed, 20 insertions, 30 deletions
diff --git a/ext/B/t/sv_stash.t b/ext/B/t/sv_stash.t index e9abf4d55d..eaaabcf8fe 100644 --- a/ext/B/t/sv_stash.t +++ b/ext/B/t/sv_stash.t @@ -14,6 +14,7 @@ plan 1; # RT #126410 = used to coredump when doing SvSTASH on %version:: TODO: { + local $TODO = 'Broken since c07f9fb2c7 - revert of a revert: slowed down detruction with no DESTROY'; fresh_perl_is( 'use B; version->new("v5.22.0"); $s = B::svref_2object(\%version::); $s->SvSTASH; print "ok\n"', "ok\n", { stderr => 1 }, 'RT #126410 - SvSTASH against %version::' @@ -82,7 +82,6 @@ struct mro_meta { const struct mro_alg *mro_which; /* which mro alg is in use? */ HV *isa; /* Everything this class @ISA */ HV *super; /* SUPER method cache */ - CV *destroy; /* DESTROY method if destroy_gen non-zero */ U32 destroy_gen; /* Generation number of DESTROY cache */ }; diff --git a/mro_core.c b/mro_core.c index e15d47fea3..25d30d9067 100644 --- a/mro_core.c +++ b/mro_core.c @@ -191,10 +191,6 @@ Perl_mro_meta_dup(pTHX_ struct mro_meta* smeta, CLONE_PARAMS* param) newmeta->super = NULL; - /* clear the destructor cache */ - newmeta->destroy = NULL; - newmeta->destroy_gen = 0; - return newmeta; } @@ -542,8 +538,8 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash) /* pessimise derefs for now. Will get recalculated by Gv_AMupdate() */ HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_NO_DEREF; - /* DESTROY can be cached in meta. */ - meta->destroy_gen = 0; + /* DESTROY can be cached in SvSTASH. */ + if (!SvOBJECT(stash)) SvSTASH(stash) = NULL; /* Iterate the isarev (classes that are our children), wiping out their linearization, method and isa caches @@ -1324,8 +1320,8 @@ Perl_mro_method_changed_in(pTHX_ HV *stash) /* Inc the package generation, since a local method changed */ HvMROMETA(stash)->pkg_gen++; - /* DESTROY can be cached in meta */ - HvMROMETA(stash)->destroy_gen = 0; + /* DESTROY can be cached in SvSTASH. */ + if (!SvOBJECT(stash)) SvSTASH(stash) = NULL; /* If stash is UNIVERSAL, or one of UNIVERSAL's parents, invalidate all method caches globally */ @@ -1350,7 +1346,7 @@ Perl_mro_method_changed_in(pTHX_ HV *stash) mrometa->cache_gen++; if(mrometa->mro_nextmethod) hv_clear(mrometa->mro_nextmethod); - mrometa->destroy_gen = 0; + if (!SvOBJECT(revstash)) SvSTASH(revstash) = NULL; } } @@ -6890,31 +6890,25 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) { assert(SvTYPE(stash) == SVt_PVHV); if (HvNAME(stash)) { CV* destructor = NULL; - struct mro_meta *meta; assert (SvOOK(stash)); - - DEBUG_o( Perl_deb(aTHX_ "Looking for DESTROY method for %s\n", - HvNAME(stash)) ); - - /* don't make this an initialization above the assert, since it needs - an AUX structure */ - meta = HvMROMETA(stash); - if (meta->destroy_gen && meta->destroy_gen == PL_sub_generation) { - destructor = meta->destroy; - DEBUG_o( Perl_deb(aTHX_ "Using cached DESTROY method %p for %s\n", - (void *)destructor, HvNAME(stash)) ); - } - else { + if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash); + if (!destructor || HvMROMETA(stash)->destroy_gen + != PL_sub_generation) + { GV * const gv = gv_fetchmeth_autoload(stash, "DESTROY", 7, 0); if (gv) destructor = GvCV(gv); - meta->destroy_gen = PL_sub_generation; - meta->destroy = destructor; - DEBUG_o( Perl_deb(aTHX_ "Set cached DESTROY method %p for %s\n", - (void *)destructor, HvNAME(stash)) ); + if (!SvOBJECT(stash)) + { + SvSTASH(stash) = + destructor ? (HV *)destructor : ((HV *)0)+1; + HvAUX(stash)->xhv_mro_meta->destroy_gen = + PL_sub_generation; + } } - assert(!destructor || SvTYPE(destructor) == SVt_PVCV); - if (destructor + assert(!destructor || destructor == ((CV *)0)+1 + || SvTYPE(destructor) == SVt_PVCV); + if (destructor && destructor != ((CV *)0)+1 /* A constant subroutine can have no side effects, so don't bother calling it. */ && !CvCONST(destructor) |