From: Joshua Pritikin <joshua.pritikin@db.com>
Date: Thu, 9 Jul 1998 09:22:46 +0000 (-0400)
Subject: add more correct version of change#1350 (as yet untested)
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=005a453cfb613e5ffe5868c1301958751100cbdf;p=p5sagit%2Fp5-mst-13.2.git

add more correct version of change#1350 (as yet untested)
	Message-Id: <H00000e50008f277@MHS>
	Subject: Re: [PATCH _70] cache missing methods

p4raw-link: @1350 on //depot/perl: a4bb25971c379e48da873823e220bdef09e90ab9

p4raw-id: //depot/perl@1404
---

diff --git a/embedvar.h b/embedvar.h
index 8225e8f..2468aa3 100644
--- a/embedvar.h
+++ b/embedvar.h
@@ -243,6 +243,7 @@
 #define stdingv			(curinterp->Istdingv)
 #define strchop			(curinterp->Istrchop)
 #define strtab			(curinterp->Istrtab)
+#define sub_generation		(curinterp->Isub_generation)
 #define sublex_info		(curinterp->Isublex_info)
 #define sv_arenaroot		(curinterp->Isv_arenaroot)
 #define sv_count		(curinterp->Isv_count)
@@ -420,6 +421,7 @@
 #define Istdingv		stdingv
 #define Istrchop		strchop
 #define Istrtab			strtab
+#define Isub_generation		sub_generation
 #define Isublex_info		sublex_info
 #define Isv_arenaroot		sv_arenaroot
 #define Isv_count		sv_count
@@ -659,6 +661,7 @@
 #define stdingv			Perl_stdingv
 #define strchop			Perl_strchop
 #define strtab			Perl_strtab
+#define sub_generation		Perl_sub_generation
 #define sublex_info		Perl_sublex_info
 #define sv_arenaroot		Perl_sv_arenaroot
 #define sv_count		Perl_sv_count
@@ -886,7 +889,6 @@
 #define sh_path			(Perl_Vars.Gsh_path)
 #define sighandlerp		(Perl_Vars.Gsighandlerp)
 #define specialsv_list		(Perl_Vars.Gspecialsv_list)
-#define sub_generation		(Perl_Vars.Gsub_generation)
 #define subline			(Perl_Vars.Gsubline)
 #define subname			(Perl_Vars.Gsubname)
 #define sv_mutex		(Perl_Vars.Gsv_mutex)
@@ -997,7 +999,6 @@
 #define Gsh_path		sh_path
 #define Gsighandlerp		sighandlerp
 #define Gspecialsv_list		specialsv_list
-#define Gsub_generation		sub_generation
 #define Gsubline		subline
 #define Gsubname		subname
 #define Gsv_mutex		sv_mutex
@@ -1108,7 +1109,6 @@
 #define sh_path			Perl_sh_path
 #define sighandlerp		Perl_sighandlerp
 #define specialsv_list		Perl_specialsv_list
-#define sub_generation		Perl_sub_generation
 #define subline			Perl_subline
 #define subname			Perl_subname
 #define sv_mutex		Perl_sv_mutex
diff --git a/gv.c b/gv.c
index 07c0b19..505f633 100644
--- a/gv.c
+++ b/gv.c
@@ -103,6 +103,7 @@ gv_init(GV *gv, HV *stash, char *name, STRLEN len, int multi)
     GvSV(gv) = NEWSV(72,0);
     GvLINE(gv) = curcop->cop_line;
     GvFILEGV(gv) = curcop->cop_filegv;
+    GvCVGEN(gv) = 0;
     GvEGV(gv) = gv;
     sv_magic((SV*)gv, (SV*)gv, '*', name, len);
     GvSTASH(gv) = (HV*)SvREFCNT_inc(stash);
@@ -117,7 +118,6 @@ gv_init(GV *gv, HV *stash, char *name, STRLEN len, int multi)
 	GvCV(gv) = compcv;
 	LEAVE;
 
-	GvCVGEN(gv) = 0;
 	sub_generation++;
 	CvGV(GvCV(gv)) = (GV*)SvREFCNT_inc(gv);
 	CvFILEGV(GvCV(gv)) = curcop->cop_filegv;
@@ -176,13 +176,15 @@ gv_fetchmeth(HV *stash, char *name, STRLEN len, I32 level)
 	    gv_init(topgv, stash, name, len, TRUE);
 	if (cv = GvCV(topgv)) {
 	    /* If genuine method or valid cache entry, use it */
-	    if (!GvCVGEN(topgv) || GvCVGEN(topgv) >= sub_generation)
+	    if (!GvCVGEN(topgv) || GvCVGEN(topgv) == sub_generation)
 		return topgv;
 	    /* Stale cached entry: junk it */
 	    SvREFCNT_dec(cv);
 	    GvCV(topgv) = cv = Nullcv;
 	    GvCVGEN(topgv) = 0;
 	}
+	else if (GvCVGEN(topgv) == sub_generation)
+	    return 0;  /* cache indicates sub doesn't exist */
     }
 
     gvp = (GV**)hv_fetch(stash, "ISA", 3, FALSE);
@@ -258,6 +260,10 @@ gv_fetchmeth(HV *stash, char *name, STRLEN len, I32 level)
 		}
 		return gv;
 	    }
+	    else if (topgv && GvREFCNT(topgv) == 1) {
+		/* cache the fact that the method is not defined */
+		GvCVGEN(topgv) = sub_generation;
+	    }
 	}
     }
 
diff --git a/interp.sym b/interp.sym
index e491d05..6270324 100644
--- a/interp.sym
+++ b/interp.sym
@@ -184,6 +184,7 @@ statusvalue_vms
 stdingv
 strchop
 strtab
+sub_generation
 sublex_info
 sv_count
 sv_objcount
diff --git a/intrpvar.h b/intrpvar.h
index 1ff9ac8..73cc5f3 100644
--- a/intrpvar.h
+++ b/intrpvar.h
@@ -104,6 +104,7 @@ PERLVAR(Ibeginav,	AV *)		/* names of BEGIN subroutines */
 PERLVAR(Iendav,		AV *)		/* names of END subroutines */
 PERLVAR(Iinitav,	AV *)		/* names of INIT subroutines */
 PERLVAR(Istrtab,	HV *)		/* shared string table */
+PERLVARI(Isub_generation,U32,1)		/* incr to invalidate method cache */
 
 /* memory management */
 PERLVAR(Isv_count,	I32)		/* how many SV* are currently allocated */
diff --git a/perlvars.h b/perlvars.h
index 115ec5a..4e9d3b8 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -50,7 +50,6 @@ PERLVAR(Gan,		U32)		/* malloc sequence number */
 PERLVAR(Gcop_seqmax,	U32)		/* statement sequence number */
 PERLVAR(Gop_seqmax,	U16)		/* op sequence number */
 PERLVAR(Gevalseq,	U32)		/* eval sequence number */
-PERLVAR(Gsub_generation,U32)		/* incr to invalidate method cache */
 PERLVAR(Gorigenviron,	char **)
 PERLVAR(Gorigalen,	U32)
 PERLVAR(Gpidstatus,	HV *)		/* pid-to-status mappings for waitpid */