Fix a bug in method caching. Better version (broader) of change #29336.
Brandon Black [Thu, 26 Apr 2007 10:52:20 +0000 (05:52 -0500)]
Subject: Re: mro status, etc
From: "Brandon Black" <blblack@gmail.com>
Message-ID: <84621a60704260852y5a3dd2a5jeb633bb46cc7a8c0@mail.gmail.com>
p4raw-link: @29336 on //depot/perl: ae6d515f69537dd5e2631b15104c2c90d022fd19

p4raw-id: //depot/perl@31091

pp_hot.c
sv.c
t/mro/method_caching.t

index 034495d..0fcec7e 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -180,11 +180,6 @@ PP(pp_sassign)
            SvREFCNT_dec(cv);
            LEAVE;
        }
-
-       if (strEQ(GvNAME(right),"isa")) {
-           GvCVGEN(right) = 0;
-           ++PL_sub_generation; /* I don't get this at all --blblack */
-       }
     }
     SvSetMagicSV(right, left);
     SETs(right);
diff --git a/sv.c b/sv.c
index 879aec9..c6e2d57 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -3237,18 +3237,18 @@ S_glob_assign_ref(pTHX_ SV *dstr, SV *sstr) {
     common:
        if (intro) {
            if (stype == SVt_PVCV) {
-               if (GvCVGEN(dstr) && GvCV(dstr) != (CV*)sref) {
+               /*if (GvCVGEN(dstr) && (GvCV(dstr) != (CV*)sref || GvCVGEN(dstr))) {*/
+               if (GvCVGEN(dstr)) {
                    SvREFCNT_dec(GvCV(dstr));
                    GvCV(dstr) = NULL;
                    GvCVGEN(dstr) = 0; /* Switch off cacheness. */
-                   mro_method_changed_in(GvSTASH(dstr));
                }
            }
            SAVEGENERICSV(*location);
        }
        else
            dref = *location;
-       if (stype == SVt_PVCV && *location != sref) {
+       if (stype == SVt_PVCV && (*location != sref || GvCVGEN(dstr))) {
            CV* const cv = (CV*)*location;
            if (cv) {
                if (!GvCVGEN((GV*)dstr) &&
index dd70da6..a20da2a 100644 (file)
@@ -38,6 +38,7 @@ my @testsubs = (
     sub { undef *MCTest::Base::foo; eval { MCTest::Derived->foo(0) }; like($@, qr/locate object method/); },
     sub { sub MCTest::Base::foo($); *MCTest::Base::foo = \&ASDF::asdf; is(MCTest::Derived->foo(0), 7); },
     sub { *XYZ = sub { $_[1]+8 }; ${MCTest::Base::}{foo} = \&XYZ; is(MCTest::Derived->foo(0), 8); },
+    sub { *MCTest::Derived::foo = \&MCTest::Base::foo; eval { MCTest::Derived::foo(0,0) }; ok(!$@); undef *MCTest::Derived::foo },
 );
 
 plan(tests => scalar(@testsubs) + 1);