From: Gurusamy Sarathy <gsar@cpan.org>
Date: Thu, 11 Nov 1999 10:32:54 +0000 (+0000)
Subject: avoid stash pointers in optree under USE_ITHREADS
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=11faa288e292c27cb2ddc4ccdc483b523d26ce19;p=p5sagit%2Fp5-mst-13.2.git

avoid stash pointers in optree under USE_ITHREADS

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

diff --git a/bytecode.pl b/bytecode.pl
index 9837d53..00df48b 100644
--- a/bytecode.pl
+++ b/bytecode.pl
@@ -400,7 +400,7 @@ op_redoop	cLOOP->op_redoop			opindex
 op_nextop	cLOOP->op_nextop			opindex
 op_lastop	cLOOP->op_lastop			opindex
 cop_label	cCOP->cop_label				pvcontents
-cop_stash	*(SV**)&cCOP->cop_stash			svindex
+cop_stashpv	cCOP					pvcontents	x
 cop_file	cCOP					pvcontents	x
 cop_seq		cCOP->cop_seq				U32
 cop_arybase	cCOP->cop_arybase			I32
diff --git a/cop.h b/cop.h
index 89fab94..d5f7f42 100644
--- a/cop.h
+++ b/cop.h
@@ -10,10 +10,11 @@
 struct cop {
     BASEOP
     char *	cop_label;	/* label for this construct */
-    HV *	cop_stash;	/* package line was compiled in */
 #ifdef USE_ITHREADS
+    char *	cop_stashpv;	/* package line was compiled in */
     char *	cop_file;	/* file name the following line # is from */
 #else
+    HV *	cop_stash;	/* package line was compiled in */
     GV *	cop_filegv;	/* file the following line # is from */
 #endif
     U32		cop_seq;	/* parse sequence number */
@@ -33,11 +34,11 @@ struct cop {
 				 ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv)
 #  define CopFILEAV(c)		(CopFILE(c) \
 				 ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav)
-#  define CopSTASH(c)		(CopSTASHPV(c) \
-				 ? gv_fetchstash(CopSTASHPV(c)) : Nullhv)
-#  define CopSTASH_set(c,hv)	((c)->cop_stashpv = HvNAME(hv))	/* XXX */
-#  define CopSTASHPV_set(c,pv)	((c)->cop_stashpv = pv)
 #  define CopSTASHPV(c)		((c)->cop_stashpv)
+#  define CopSTASHPV_set(c,pv)	((c)->cop_stashpv = savepv(pv))	/* XXX */
+#  define CopSTASH(c)		(CopSTASHPV(c) \
+				 ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv)
+#  define CopSTASH_set(c,hv)	CopSTASHPV_set(c, HvNAME(hv))
 #else
 #  define CopFILEGV(c)		((c)->cop_filegv)
 #  define CopFILEGV_set(c,gv)	((c)->cop_filegv = gv)
@@ -48,6 +49,7 @@ struct cop {
 #  define CopSTASH(c)		((c)->cop_stash)
 #  define CopSTASH_set(c,hv)	((c)->cop_stash = hv)
 #  define CopSTASHPV(c)		(CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch)
+#  define CopSTASHPV_set(c,pv)	CopSTASH_set(c, gv_stashpv(pv,GV_ADD))
 #endif /* USE_ITHREADS */
 
 #define CopLINE(c)		((c)->cop_line)
diff --git a/ext/B/B.xs b/ext/B/B.xs
index cef9ecb..4867e71 100644
--- a/ext/B/B.xs
+++ b/ext/B/B.xs
@@ -746,7 +746,8 @@ LOOP_lastop(o)
 	B::LOOP	o
 
 #define COP_label(o)	o->cop_label
-#define COP_stash(o)	o->cop_stash
+#define COP_stashpv(o)	CopSTASHPV(o)
+#define COP_stash(o)	CopSTASH(o)
 #define COP_file(o)	CopFILE(o)
 #define COP_cop_seq(o)	o->cop_seq
 #define COP_arybase(o)	o->cop_arybase
@@ -759,6 +760,10 @@ char *
 COP_label(o)
 	B::COP	o
 
+char *
+COP_stashpv(o)
+	B::COP	o
+
 B::HV
 COP_stash(o)
 	B::COP	o
diff --git a/ext/B/B/Asmdata.pm b/ext/B/B/Asmdata.pm
index 7d37616..a7dbbe2 100644
--- a/ext/B/B/Asmdata.pm
+++ b/ext/B/B/Asmdata.pm
@@ -129,7 +129,7 @@ $insn_data{op_redoop} = [105, \&PUT_opindex, "GET_opindex"];
 $insn_data{op_nextop} = [106, \&PUT_opindex, "GET_opindex"];
 $insn_data{op_lastop} = [107, \&PUT_opindex, "GET_opindex"];
 $insn_data{cop_label} = [108, \&PUT_pvcontents, "GET_pvcontents"];
-$insn_data{cop_stash} = [109, \&PUT_svindex, "GET_svindex"];
+$insn_data{cop_stashpv} = [109, \&PUT_pvcontents, "GET_pvcontents"];
 $insn_data{cop_file} = [110, \&PUT_pvcontents, "GET_pvcontents"];
 $insn_data{cop_seq} = [111, \&PUT_U32, "GET_U32"];
 $insn_data{cop_arybase} = [112, \&PUT_I32, "GET_I32"];
diff --git a/ext/B/B/Bytecode.pm b/ext/B/B/Bytecode.pm
index 382a591..8764a0d 100644
--- a/ext/B/B/Bytecode.pm
+++ b/ext/B/B/Bytecode.pm
@@ -278,8 +278,7 @@ sub B::LOOP::bytecode {
 
 sub B::COP::bytecode {
     my $op = shift;
-    my $stash = $op->stash;
-    my $stashix = $stash->objix;
+    my $stashpv = $op->stashpv;
     my $file = $op->file;
     my $line = $op->line;
     my $warnings = $op->warnings;
@@ -288,10 +287,11 @@ sub B::COP::bytecode {
 	printf "# line %s:%d\n", $file, $line;
     }
     $op->B::OP::bytecode;
-    printf <<"EOT", pvstring($op->label), $op->cop_seq, pvstring($file), $op->arybase;
+    printf <<"EOT", pvstring($op->label), pvstring($stashpv), $op->cop_seq, pvstring($file), $op->arybase;
 newpv %s
 cop_label
-cop_stash $stashix
+newpv %s
+cop_stashpv
 cop_seq %d
 newpv %s
 cop_file
diff --git a/ext/B/B/C.pm b/ext/B/B/C.pm
index 192ecef..f860744 100644
--- a/ext/B/B/C.pm
+++ b/ext/B/B/C.pm
@@ -293,7 +293,6 @@ sub B::COP::save {
     my ($op, $level) = @_;
     my $sym = objsym($op);
     return $sym if defined $sym;
-    my $stashsym = $op->stash->save;
     warn sprintf("COP: line %d file %s\n", $op->line, $op->file)
 	if $debug_cops;
     $copsect->add(sprintf("s\\_%x, s\\_%x, %s,$handle_VC_problem %u, %u, %u, 0x%x, 0x%x, %s, Nullhv, Nullgv, %u, %d, %u",
@@ -303,7 +302,7 @@ sub B::COP::save {
 			  $op->arybase, $op->line));
     my $copix = $copsect->index;
     $init->add(sprintf("CopFILE_set(&cop_list[%d], %s);", $copix, cstring($op->file)),
-	       sprintf("cop_list[%d].cop_stash = %s;", $copix, $stashsym));
+	       sprintf("CopSTASHPV_set(&cop_list[%d], %s);", $copix, cstring($op->stashpv));
     savesym($op, "(OP*)&cop_list[$copix]");
 }
 
diff --git a/ext/B/B/Debug.pm b/ext/B/B/Debug.pm
index 7623e9b..ae7a973 100644
--- a/ext/B/B/Debug.pm
+++ b/ext/B/B/Debug.pm
@@ -60,9 +60,9 @@ sub B::PMOP::debug {
 sub B::COP::debug {
     my ($op) = @_;
     $op->B::OP::debug();
-    printf <<'EOT', $op->label, ${$op->stash}, $op->file, $op->seq, $op->arybase, $op->line, ${$op->warnings};
+    printf <<'EOT', $op->label, $op->stashpv, $op->file, $op->seq, $op->arybase, $op->line, ${$op->warnings};
 	cop_label	%s
-	cop_stash	0x%x
+	cop_stashpv	%s
 	cop_file	%s
 	cop_seq		%d
 	cop_arybase	%d
diff --git a/ext/B/B/Deparse.pm b/ext/B/B/Deparse.pm
index 7509b96..be7088e 100644
--- a/ext/B/B/Deparse.pm
+++ b/ext/B/B/Deparse.pm
@@ -770,7 +770,7 @@ sub pp_nextstate {
 	   and $seq > $self->{'subs_todo'}[0][0]) {
 	push @text, $self->next_todo;
     }
-    my $stash = $op->stash->NAME;
+    my $stash = $op->stashpv;
     if ($stash ne $self->{'curstash'}) {
 	push @text, "package $stash;\n";
 	$self->{'curstash'} = $stash;
diff --git a/ext/ByteLoader/bytecode.h b/ext/ByteLoader/bytecode.h
index 77d93b0..6e19e12 100644
--- a/ext/ByteLoader/bytecode.h
+++ b/ext/ByteLoader/bytecode.h
@@ -137,8 +137,9 @@ typedef IV IV64;
 	PL_comppad = (AV *)arg;			\
 	pad = AvARRAY(arg);			\
     } STMT_END
-#define BSET_cop_file(cop, arg) CopFILE_set(cop,arg)
-#define BSET_cop_line(cop, arg) CopLINE_set(cop,arg)
+#define BSET_cop_file(cop, arg)		CopFILE_set(cop,arg)
+#define BSET_cop_line(cop, arg)		CopLINE_set(cop,arg)
+#define BSET_cop_stashpv(cop, arg)	CopSTASHPV_set(cop,arg)
 
 #define BSET_OBJ_STORE(obj, ix)		\
 	(I32)ix > bytecode_obj_list_fill ?	\
diff --git a/ext/ByteLoader/byterun.c b/ext/ByteLoader/byterun.c
index f55feb7..595fd4e 100644
--- a/ext/ByteLoader/byterun.c
+++ b/ext/ByteLoader/byterun.c
@@ -828,11 +828,11 @@ byterun(pTHXo_ struct bytestream bs)
 		cCOP->cop_label = arg;
 		break;
 	    }
-	  case INSN_COP_STASH:		/* 109 */
+	  case INSN_COP_STASHPV:		/* 109 */
 	    {
-		svindex arg;
-		BGET_svindex(arg);
-		*(SV**)&cCOP->cop_stash = arg;
+		pvcontents arg;
+		BGET_pvcontents(arg);
+		BSET_cop_stashpv(cCOP, arg);
 		break;
 	    }
 	  case INSN_COP_FILE:		/* 110 */
diff --git a/ext/ByteLoader/byterun.h b/ext/ByteLoader/byterun.h
index 17560c8..f0de6b4 100644
--- a/ext/ByteLoader/byterun.h
+++ b/ext/ByteLoader/byterun.h
@@ -125,7 +125,7 @@ enum {
     INSN_OP_NEXTOP,			/* 106 */
     INSN_OP_LASTOP,			/* 107 */
     INSN_COP_LABEL,			/* 108 */
-    INSN_COP_STASH,			/* 109 */
+    INSN_COP_STASHPV,			/* 109 */
     INSN_COP_FILE,			/* 110 */
     INSN_COP_SEQ,			/* 111 */
     INSN_COP_ARYBASE,			/* 112 */
diff --git a/gv.c b/gv.c
index 50dc34d..b662141 100644
--- a/gv.c
+++ b/gv.c
@@ -300,7 +300,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 	if ((nsplit - origname) == 5 && strnEQ(origname, "SUPER", 5)) {
 	    /* ->SUPER::method should really be looked up in original stash */
 	    SV *tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER",
-					     HvNAME(PL_curcop->cop_stash)));
+						  CopSTASHPV(PL_curcop)));
 	    stash = gv_stashpvn(SvPVX(tmpstr), SvCUR(tmpstr), TRUE);
 	    DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n",
 			 origname, HvNAME(stash), name) );
@@ -559,7 +559,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
 		}
 	    }
 	    else
-		stash = PL_curcop->cop_stash;
+		stash = CopSTASH(PL_curcop);
 	}
 	else
 	    stash = PL_defstash;
diff --git a/op.c b/op.c
index 7e8d32e..bd8f652 100644
--- a/op.c
+++ b/op.c
@@ -776,7 +776,9 @@ S_cop_free(pTHX_ COP* cop)
     Safefree(cop->cop_label);
 #ifdef USE_ITHREADS
     Safefree(CopFILE(cop));		/* XXXXX share in a pvtable? */
+    Safefree(CopSTASHPV(cop));		/* XXXXX share in a pvtable? */
 #else
+    /* NOTE: COP.cop_stash is not refcounted */
     SvREFCNT_dec(CopFILEGV(cop));
 #endif
     if (! specialWARN(cop->cop_warnings))
@@ -3330,7 +3332,7 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
 #else
     CopFILEGV_set(cop, (GV*)SvREFCNT_inc(CopFILEGV(PL_curcop)));
 #endif
-    cop->cop_stash = PL_curstash;
+    CopSTASH_set(cop, PL_curstash);
 
     if (PERLDB_LINE && PL_curstash != PL_debstash) {
 	SV **svp = av_fetch(CopFILEAV(PL_curcop), (I32)CopLINE(cop), FALSE);
@@ -4496,15 +4498,24 @@ void
 Perl_newCONSTSUB(pTHX_ HV *stash, char *name, SV *sv)
 {
     dTHR;
-    U32 oldhints = PL_hints;
-    HV *old_cop_stash = PL_curcop->cop_stash;
-    HV *old_curstash = PL_curstash;
-    line_t oldline = CopLINE(PL_curcop);
-    CopLINE_set(PL_curcop, PL_copline);
 
+    ENTER;
+    SAVECOPLINE(PL_curcop);
+    SAVEHINTS();
+
+    CopLINE_set(PL_curcop, PL_copline);
     PL_hints &= ~HINT_BLOCK_SCOPE;
-    if(stash)
-	PL_curstash = PL_curcop->cop_stash = stash;
+
+    if (stash) {
+	SAVESPTR(PL_curstash);
+	SAVECOPSTASH(PL_curcop);
+	PL_curstash = stash;
+#ifdef USE_ITHREADS
+	CopSTASHPV(PL_curcop) = stash ? HvNAME(stash) : Nullch;
+#else
+	CopSTASH(PL_curcop) = stash;
+#endif
+    }
 
     newATTRSUB(
 	start_subparse(FALSE, 0),
@@ -4514,10 +4525,7 @@ Perl_newCONSTSUB(pTHX_ HV *stash, char *name, SV *sv)
 	newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
     );
 
-    PL_hints = oldhints;
-    PL_curcop->cop_stash = old_cop_stash;
-    PL_curstash = old_curstash;
-    CopLINE_set(PL_curcop, oldline);
+    LEAVE;
 }
 
 CV *
diff --git a/perl.c b/perl.c
index 476616a..11a06bd 100644
--- a/perl.c
+++ b/perl.c
@@ -2084,7 +2084,7 @@ S_init_main_stash(pTHX)
     sv_grow(ERRSV, 240);	/* Preallocate - for immediate signals. */
     sv_setpvn(ERRSV, "", 0);
     PL_curstash = PL_defstash;
-    PL_compiling.cop_stash = PL_defstash;
+    CopSTASH_set(&PL_compiling, PL_defstash);
     PL_globalstash = GvHV(gv_fetchpv("CORE::GLOBAL::", GV_ADDMULTI, SVt_PVHV));
     /* We must init $/ before switches are processed. */
     sv_setpvn(get_sv("/", TRUE), "\n", 1);
diff --git a/pp.c b/pp.c
index c04d7b2..1fb26c3 100644
--- a/pp.c
+++ b/pp.c
@@ -254,7 +254,7 @@ PP(pp_rv2gv)
 			    }
 			}
 		    }
-		    gv_init(gv, PL_curcop->cop_stash, name, len, 0);
+		    gv_init(gv, CopSTASH(PL_curcop), name, len, 0);
 		    sv_upgrade(sv, SVt_RV);
 		    SvRV(sv) = (SV *) gv;
 		    SvROK_on(sv);
@@ -581,7 +581,7 @@ PP(pp_bless)
     HV *stash;
 
     if (MAXARG == 1)
-	stash = PL_curcop->cop_stash;
+	stash = CopSTASH(PL_curcop);
     else {
 	SV *ssv = POPs;
 	STRLEN len;
diff --git a/pp_ctl.c b/pp_ctl.c
index 301d1bc..22c83aa 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -792,7 +792,7 @@ PP(pp_sort)
 	    kid = kUNOP->op_first;			/* pass rv2gv */
 	    kid = kUNOP->op_first;			/* pass leave */
 	    PL_sortcop = kid->op_next;
-	    stash = PL_curcop->cop_stash;
+	    stash = CopSTASH(PL_curcop);
 	}
 	else {
 	    cv = sv_2cv(*++MARK, &stash, &gv, 0);
@@ -822,7 +822,7 @@ PP(pp_sort)
     }
     else {
 	PL_sortcop = Nullop;
-	stash = PL_curcop->cop_stash;
+	stash = CopSTASH(PL_curcop);
     }
 
     up = myorigmark + 1;
@@ -1428,8 +1428,8 @@ PP(pp_caller)
 	    cx = &ccstack[dbcxix];
     }
 
+    hv = CopSTASH(cx->blk_oldcop);
     if (GIMME != G_ARRAY) {
-	hv = cx->blk_oldcop->cop_stash;
 	if (!hv)
 	    PUSHs(&PL_sv_undef);
 	else {
@@ -1440,7 +1440,6 @@ PP(pp_caller)
 	RETURN;
     }
 
-    hv = cx->blk_oldcop->cop_stash;
     if (!hv)
 	PUSHs(&PL_sv_undef);
     else
@@ -1480,7 +1479,7 @@ PP(pp_caller)
 	PUSHs(&PL_sv_undef);
     }
     if (CxTYPE(cx) == CXt_SUB && cx->blk_sub.hasargs
-	&& PL_curcop->cop_stash == PL_debstash)
+	&& CopSTASH(PL_curcop) == PL_debstash)
     {
 	AV *ary = cx->blk_sub.argarray;
 	int off = AvARRAY(ary) - AvALLOC(ary);
@@ -1516,7 +1515,7 @@ PP(pp_reset)
 	tmps = "";
     else
 	tmps = POPpx;
-    sv_reset(tmps, PL_curcop->cop_stash);
+    sv_reset(tmps, CopSTASH(PL_curcop));
     PUSHs(&PL_sv_yes);
     RETURN;
 }
@@ -2488,8 +2487,8 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp)
     /* switch to eval mode */
 
     if (PL_curcop == &PL_compiling) {
-	SAVESPTR(PL_compiling.cop_stash);
-	PL_compiling.cop_stash = PL_curstash;
+	SAVECOPSTASH(&PL_compiling);
+	CopSTASH_set(&PL_compiling, PL_curstash);
     }
     SAVECOPFILE(&PL_compiling);
     SAVECOPLINE(&PL_compiling);
@@ -2605,7 +2604,7 @@ S_doeval(pTHX_ int gimme, OP** startop)
 
     /* make sure we compile in the right package */
 
-    newstash = PL_curcop->cop_stash;
+    newstash = CopSTASH(PL_curcop);
     if (PL_curstash != newstash) {
 	SAVESPTR(PL_curstash);
 	PL_curstash = newstash;
diff --git a/pp_hot.c b/pp_hot.c
index 815ddd8..f2e8e21 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2778,7 +2778,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
 		sep = p, leaf = p + 2;
 	}
 	if (!sep || ((sep - name) == 5 && strnEQ(name, "SUPER", 5))) {
-	    packname = HvNAME(sep ? PL_curcop->cop_stash : stash);
+	    packname = sep ? CopSTASHPV(PL_curcop) : HvNAME(stash);
 	    packlen = strlen(packname);
 	}
 	else {
diff --git a/scope.h b/scope.h
index b949567..6aca9ea 100644
--- a/scope.h
+++ b/scope.h
@@ -111,8 +111,10 @@
     } STMT_END
 
 #ifdef USE_ITHREADS
+#  define SAVECOPSTASH(cop)	SAVEPPTR(CopSTASHPV(cop))
 #  define SAVECOPFILE(cop)	SAVEPPTR(CopFILE(cop))
 #else
+#  define SAVECOPSTASH(cop)	SAVESPTR(CopSTASH(cop))
 #  define SAVECOPFILE(cop)	SAVESPTR(CopFILEGV(cop))
 #endif
 
diff --git a/sv.c b/sv.c
index 8c52c57..6e96590 100644
--- a/sv.c
+++ b/sv.c
@@ -2369,8 +2369,11 @@ Perl_sv_setsv(pTHX_ SV *dstr, register SV *sstr)
 		 SvTYPE(SvRV(sstr)) == SVt_PVGV) {
 	    sstr = SvRV(sstr);
 	    if (sstr == dstr) {
-		if (PL_curcop->cop_stash != GvSTASH(dstr))
+		if (GvIMPORTED(dstr) != GVf_IMPORTED
+		    && CopSTASH(PL_curcop) != GvSTASH(dstr))
+		{
 		    GvIMPORTED_on(dstr);
+		}
 		GvMULTI_on(dstr);
 		return;
 	    }
@@ -2424,8 +2427,11 @@ Perl_sv_setsv(pTHX_ SV *dstr, register SV *sstr)
 	    gp_free((GV*)dstr);
 	    GvGP(dstr) = gp_ref(GvGP(sstr));
 	    SvTAINT(dstr);
-	    if (PL_curcop->cop_stash != GvSTASH(dstr))
+	    if (GvIMPORTED(dstr) != GVf_IMPORTED
+		&& CopSTASH(PL_curcop) != GvSTASH(dstr))
+	    {
 		GvIMPORTED_on(dstr);
+	    }
 	    GvMULTI_on(dstr);
 	    return;
 	}
@@ -2473,8 +2479,11 @@ Perl_sv_setsv(pTHX_ SV *dstr, register SV *sstr)
 		    else
 			dref = (SV*)GvAV(dstr);
 		    GvAV(dstr) = (AV*)sref;
-		    if (PL_curcop->cop_stash != GvSTASH(dstr))
+		    if (GvIMPORTED_AV_off(dstr)
+			&& CopSTASH(PL_curcop) != GvSTASH(dstr))
+		    {
 			GvIMPORTED_AV_on(dstr);
+		    }
 		    break;
 		case SVt_PVHV:
 		    if (intro)
@@ -2482,8 +2491,11 @@ Perl_sv_setsv(pTHX_ SV *dstr, register SV *sstr)
 		    else
 			dref = (SV*)GvHV(dstr);
 		    GvHV(dstr) = (HV*)sref;
-		    if (PL_curcop->cop_stash != GvSTASH(dstr))
+		    if (GvIMPORTED_HV_off(dstr)
+			&& CopSTASH(PL_curcop) != GvSTASH(dstr))
+		    {
 			GvIMPORTED_HV_on(dstr);
+		    }
 		    break;
 		case SVt_PVCV:
 		    if (intro) {
@@ -2535,8 +2547,11 @@ Perl_sv_setsv(pTHX_ SV *dstr, register SV *sstr)
 			GvASSUMECV_on(dstr);
 			PL_sub_generation++;
 		    }
-		    if (PL_curcop->cop_stash != GvSTASH(dstr))
+		    if (GvIMPORTED_CV_off(dstr)
+			&& CopSTASH(PL_curcop) != GvSTASH(dstr))
+		    {
 			GvIMPORTED_CV_on(dstr);
+		    }
 		    break;
 		case SVt_PVIO:
 		    if (intro)
@@ -2551,8 +2566,11 @@ Perl_sv_setsv(pTHX_ SV *dstr, register SV *sstr)
 		    else
 			dref = (SV*)GvSV(dstr);
 		    GvSV(dstr) = sref;
-		    if (PL_curcop->cop_stash != GvSTASH(dstr))
+		    if (GvIMPORTED_SV_off(dstr)
+			&& CopSTASH(PL_curcop) != GvSTASH(dstr))
+		    {
 			GvIMPORTED_SV_on(dstr);
+		    }
 		    break;
 		}
 		if (dref)
@@ -6175,7 +6193,7 @@ perl_clone_using(PerlInterpreter *proto_perl, IV flags,
     sv_table_store(PL_sv_table, (SV*)proto_perl->Istrtab, (SV*)PL_strtab);
 
     PL_compiling		= proto_perl->Icompiling;
-    PL_compiling.cop_stash	= hv_dup(PL_compiling.cop_stash);
+    PL_compiling.cop_stashpv	= SAVEPV(PL_compiling.cop_stashpv);
     PL_compiling.cop_file	= SAVEPV(PL_compiling.cop_file);
     PL_compiling.cop_warnings	= sv_dup_inc(PL_compiling.cop_warnings);
     if (proto_perl->Tcurcop == &proto_perl->Icompiling)