avoid stash pointers in optree under USE_ITHREADS
Gurusamy Sarathy [Thu, 11 Nov 1999 10:32:54 +0000 (10:32 +0000)]
p4raw-id: //depot/perl@4546

19 files changed:
bytecode.pl
cop.h
ext/B/B.xs
ext/B/B/Asmdata.pm
ext/B/B/Bytecode.pm
ext/B/B/C.pm
ext/B/B/Debug.pm
ext/B/B/Deparse.pm
ext/ByteLoader/bytecode.h
ext/ByteLoader/byterun.c
ext/ByteLoader/byterun.h
gv.c
op.c
perl.c
pp.c
pp_ctl.c
pp_hot.c
scope.h
sv.c

index 9837d53..00df48b 100644 (file)
@@ -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 (file)
--- a/cop.h
+++ b/cop.h
 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)
index cef9ecb..4867e71 100644 (file)
@@ -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
index 7d37616..a7dbbe2 100644 (file)
@@ -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"];
index 382a591..8764a0d 100644 (file)
@@ -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
index 192ecef..f860744 100644 (file)
@@ -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]");
 }
 
index 7623e9b..ae7a973 100644 (file)
@@ -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
index 7509b96..be7088e 100644 (file)
@@ -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;
index 77d93b0..6e19e12 100644 (file)
@@ -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 ?      \
index f55feb7..595fd4e 100644 (file)
@@ -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 */
index 17560c8..f0de6b4 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- 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;
index 301d1bc..22c83aa 100644 (file)
--- 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;
index 815ddd8..f2e8e21 100644 (file)
--- 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 (file)
--- a/scope.h
+++ b/scope.h
     } 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 (file)
--- 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)