const declaration fixup
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index 8d56ada..1a40441 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
 
 /* Hot code. */
 
-#ifdef USE_5005THREADS
-static void unset_cvowner(pTHX_ void *cvarg);
-#endif /* USE_5005THREADS */
-
 PP(pp_const)
 {
     dSP;
@@ -1470,6 +1466,8 @@ Perl_do_readline(pTHX)
                report_evil_fh(PL_last_in_gv, io, PL_op->op_type);
        }
        if (gimme == G_SCALAR) {
+           /* undef TARG, and push that undefined value */
+           SV_CHECK_THINKFIRST_COW_DROP(TARG);
            (void)SvOK_off(TARG);
            PUSHTARG;
        }
@@ -1531,6 +1529,7 @@ Perl_do_readline(pTHX)
                }
            }
            if (gimme == G_SCALAR) {
+               SV_CHECK_THINKFIRST_COW_DROP(TARG);
                (void)SvOK_off(TARG);
                SPAGAIN;
                PUSHTARG;
@@ -1772,13 +1771,11 @@ PP(pp_iter)
            STRLEN maxlen;
            char *max = SvPV((SV*)av, maxlen);
            if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) {
-#ifndef USE_5005THREADS                          /* don't risk potential race */
                if (SvREFCNT(*itersvp) == 1 && !SvMAGICAL(*itersvp)) {
                    /* safe to reuse old SV */
                    sv_setsv(*itersvp, cur);
                }
                else
-#endif
                {
                    /* we need a fresh SV every time so that loop body sees a
                     * completely new SV for closures/references to work as
@@ -1798,13 +1795,12 @@ PP(pp_iter)
        if (cx->blk_loop.iterix > cx->blk_loop.itermax)
            RETPUSHNO;
 
-#ifndef USE_5005THREADS                          /* don't risk potential race */
+       /* don't risk potential race */
        if (SvREFCNT(*itersvp) == 1 && !SvMAGICAL(*itersvp)) {
            /* safe to reuse old SV */
            sv_setiv(*itersvp, cx->blk_loop.iterix++);
        }
        else
-#endif
        {
            /* we need a fresh SV every time so that loop body sees a
             * completely new SV for closures/references to work as they
@@ -2133,7 +2129,8 @@ PP(pp_subst)
            sv_catpvn(dstr, s, strend - s);
 
        (void)SvOOK_off(TARG);
-       Safefree(SvPVX(TARG));
+       if (SvLEN(TARG))
+           Safefree(SvPVX(TARG));
        SvPVX(TARG) = SvPVX(dstr);
        SvCUR_set(TARG, SvCUR(dstr));
        SvLEN_set(TARG, SvLEN(dstr));
@@ -2324,8 +2321,9 @@ PP(pp_leavesublv)
                    PL_curpm = newpm;
                    LEAVE;
                    LEAVESUB(sv);
-                   DIE(aTHX_ "Can't return a %s from lvalue subroutine",
-                       SvREADONLY(TOPs) ? "readonly value" : "temporary");
+                   DIE(aTHX_ "Can't return %s from lvalue subroutine",
+                       SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef"
+                       : "a readonly value" : "a temporary");
                }
                else {                  /* Can be a localized value
                                         * subject to deletion. */
@@ -2463,6 +2461,16 @@ PP(pp_entersub)
     if (!sv)
        DIE(aTHX_ "Not a CODE reference");
     switch (SvTYPE(sv)) {
+       /* This is overwhelming the most common case:  */
+    case SVt_PVGV:
+       if (!(cv = GvCVu((GV*)sv)))
+           cv = sv_2cv(sv, &stash, &gv, FALSE);
+       if (!cv) {
+           ENTER;
+           SAVETMPS;
+           goto try_autoload;
+       }
+       break;
     default:
        if (!SvROK(sv)) {
            char *sym;
@@ -2500,18 +2508,10 @@ PP(pp_entersub)
     case SVt_PVHV:
     case SVt_PVAV:
        DIE(aTHX_ "Not a CODE reference");
+       /* This is the second most common case:  */
     case SVt_PVCV:
        cv = (CV*)sv;
        break;
-    case SVt_PVGV:
-       if (!(cv = GvCVu((GV*)sv)))
-           cv = sv_2cv(sv, &stash, &gv, FALSE);
-       if (!cv) {
-           ENTER;
-           SAVETMPS;
-           goto try_autoload;
-       }
-       break;
     }
 
     ENTER;
@@ -2519,35 +2519,7 @@ PP(pp_entersub)
 
   retry:
     if (!CvROOT(cv) && !CvXSUB(cv)) {
-       GV* autogv;
-       SV* sub_name;
-
-       /* anonymous or undef'd function leaves us no recourse */
-       if (CvANON(cv) || !(gv = CvGV(cv)))
-           DIE(aTHX_ "Undefined subroutine called");
-
-       /* autoloaded stub? */
-       if (cv != GvCV(gv)) {
-           cv = GvCV(gv);
-       }
-       /* should call AUTOLOAD now? */
-       else {
-try_autoload:
-           if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
-                                  FALSE)))
-           {
-               cv = GvCV(autogv);
-           }
-           /* sorry */
-           else {
-               sub_name = sv_newmortal();
-               gv_efullname3(sub_name, gv, Nullch);
-               DIE(aTHX_ "Undefined subroutine &%s called", SvPVX(sub_name));
-           }
-       }
-       if (!cv)
-           DIE(aTHX_ "Not a CODE reference");
-       goto retry;
+       goto fooey;
     }
 
     gimme = GIMME_V;
@@ -2557,208 +2529,8 @@ try_autoload:
            DIE(aTHX_ "No DBsub routine");
     }
 
-#ifdef USE_5005THREADS
-    /*
-     * First we need to check if the sub or method requires locking.
-     * If so, we gain a lock on the CV, the first argument or the
-     * stash (for static methods), as appropriate. This has to be
-     * inline because for FAKE_THREADS, COND_WAIT inlines code to
-     * reschedule by returning a new op.
-     */
-    MUTEX_LOCK(CvMUTEXP(cv));
-    if (CvFLAGS(cv) & CVf_LOCKED) {
-       MAGIC *mg;      
-       if (CvFLAGS(cv) & CVf_METHOD) {
-           if (SP > PL_stack_base + TOPMARK)
-               sv = *(PL_stack_base + TOPMARK + 1);
-           else {
-               AV *av = (AV*)PAD_SVl(0);
-               if (hasargs || !av || AvFILLp(av) < 0
-                   || !(sv = AvARRAY(av)[0]))
-               {
-                   MUTEX_UNLOCK(CvMUTEXP(cv));
-                   DIE(aTHX_ "no argument for locked method call");
-               }
-           }
-           if (SvROK(sv))
-               sv = SvRV(sv);
-           else {              
-               STRLEN len;
-               char *stashname = SvPV(sv, len);
-               sv = (SV*)gv_stashpvn(stashname, len, TRUE);
-           }
-       }
-       else {
-           sv = (SV*)cv;
-       }
-       MUTEX_UNLOCK(CvMUTEXP(cv));
-       mg = condpair_magic(sv);
-       MUTEX_LOCK(MgMUTEXP(mg));
-       if (MgOWNER(mg) == thr)
-           MUTEX_UNLOCK(MgMUTEXP(mg));
-       else {
-           while (MgOWNER(mg))
-               COND_WAIT(MgOWNERCONDP(mg), MgMUTEXP(mg));
-           MgOWNER(mg) = thr;
-           DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: pp_entersub lock %p\n",
-                                 thr, sv));
-           MUTEX_UNLOCK(MgMUTEXP(mg));
-           SAVEDESTRUCTOR_X(Perl_unlock_condpair, sv);
-       }
-       MUTEX_LOCK(CvMUTEXP(cv));
-    }
-    /*
-     * Now we have permission to enter the sub, we must distinguish
-     * four cases. (0) It's an XSUB (in which case we don't care
-     * about ownership); (1) it's ours already (and we're recursing);
-     * (2) it's free (but we may already be using a cached clone);
-     * (3) another thread owns it. Case (1) is easy: we just use it.
-     * Case (2) means we look for a clone--if we have one, use it
-     * otherwise grab ownership of cv. Case (3) means we look for a
-     * clone (for non-XSUBs) and have to create one if we don't
-     * already have one.
-     * Why look for a clone in case (2) when we could just grab
-     * ownership of cv straight away? Well, we could be recursing,
-     * i.e. we originally tried to enter cv while another thread
-     * owned it (hence we used a clone) but it has been freed up
-     * and we're now recursing into it. It may or may not be "better"
-     * to use the clone but at least CvDEPTH can be trusted.
-     */
-    if (CvOWNER(cv) == thr || CvXSUB(cv))
-       MUTEX_UNLOCK(CvMUTEXP(cv));
-    else {
-       /* Case (2) or (3) */
-       SV **svp;
-       
-       /*
-        * XXX Might it be better to release CvMUTEXP(cv) while we
-        * do the hv_fetch? We might find someone has pinched it
-        * when we look again, in which case we would be in case
-        * (3) instead of (2) so we'd have to clone. Would the fact
-        * that we released the mutex more quickly make up for this?
-        */
-       if ((svp = hv_fetch(thr->cvcache, (char *)cv, sizeof(cv), FALSE)))
-       {
-           /* We already have a clone to use */
-           MUTEX_UNLOCK(CvMUTEXP(cv));
-           cv = *(CV**)svp;
-           DEBUG_S(PerlIO_printf(Perl_debug_log,
-                                 "entersub: %p already has clone %p:%s\n",
-                                 thr, cv, SvPEEK((SV*)cv)));
-           CvOWNER(cv) = thr;
-           SvREFCNT_inc(cv);
-           if (CvDEPTH(cv) == 0)
-               SAVEDESTRUCTOR_X(unset_cvowner, (void*) cv);
-       }
-       else {
-           /* (2) => grab ownership of cv. (3) => make clone */
-           if (!CvOWNER(cv)) {
-               CvOWNER(cv) = thr;
-               SvREFCNT_inc(cv);
-               MUTEX_UNLOCK(CvMUTEXP(cv));
-               DEBUG_S(PerlIO_printf(Perl_debug_log,
-                           "entersub: %p grabbing %p:%s in stash %s\n",
-                           thr, cv, SvPEEK((SV*)cv), CvSTASH(cv) ?
-                               HvNAME(CvSTASH(cv)) : "(none)"));
-           }
-           else {
-               /* Make a new clone. */
-               CV *clonecv;
-               SvREFCNT_inc(cv); /* don't let it vanish from under us */
-               MUTEX_UNLOCK(CvMUTEXP(cv));
-               DEBUG_S((PerlIO_printf(Perl_debug_log,
-                                      "entersub: %p cloning %p:%s\n",
-                                      thr, cv, SvPEEK((SV*)cv))));
-               /*
-                * We're creating a new clone so there's no race
-                * between the original MUTEX_UNLOCK and the
-                * SvREFCNT_inc since no one will be trying to undef
-                * it out from underneath us. At least, I don't think
-                * there's a race...
-                */
-               clonecv = cv_clone(cv);
-               SvREFCNT_dec(cv); /* finished with this */
-               hv_store(thr->cvcache, (char*)cv, sizeof(cv), (SV*)clonecv,0);
-               CvOWNER(clonecv) = thr;
-               cv = clonecv;
-               SvREFCNT_inc(cv);
-           }
-           DEBUG_S(if (CvDEPTH(cv) != 0)
-                       PerlIO_printf(Perl_debug_log, "depth %ld != 0\n",
-                                     CvDEPTH(cv)));
-           SAVEDESTRUCTOR_X(unset_cvowner, (void*) cv);
-       }
-    }
-#endif /* USE_5005THREADS */
-
-    if (CvXSUB(cv)) {
-#ifdef PERL_XSUB_OLDSTYLE
-       if (CvOLDSTYLE(cv)) {
-           I32 (*fp3)(int,int,int);
-           dMARK;
-           register I32 items = SP - MARK;
-                                       /* We dont worry to copy from @_. */
-           while (SP > mark) {
-               SP[1] = SP[0];
-               SP--;
-           }
-           PL_stack_sp = mark + 1;
-           fp3 = (I32(*)(int,int,int))CvXSUB(cv);
-           items = (*fp3)(CvXSUBANY(cv).any_i32,
-                          MARK - PL_stack_base + 1,
-                          items);
-           PL_stack_sp = PL_stack_base + items;
-       }
-       else
-#endif /* PERL_XSUB_OLDSTYLE */
-       {
-           I32 markix = TOPMARK;
-
-           PUTBACK;
-
-           if (!hasargs) {
-               /* Need to copy @_ to stack. Alternative may be to
-                * switch stack to @_, and copy return values
-                * back. This would allow popping @_ in XSUB, e.g.. XXXX */
-               AV* av;
-               I32 items;
-#ifdef USE_5005THREADS
-               av = (AV*)PAD_SVl(0);
-#else
-               av = GvAV(PL_defgv);
-#endif /* USE_5005THREADS */           
-               items = AvFILLp(av) + 1;   /* @_ is not tieable */
-
-               if (items) {
-                   /* Mark is at the end of the stack. */
-                   EXTEND(SP, items);
-                   Copy(AvARRAY(av), SP + 1, items, SV*);
-                   SP += items;
-                   PUTBACK ;           
-               }
-           }
-           /* We assume first XSUB in &DB::sub is the called one. */
-           if (PL_curcopdb) {
-               SAVEVPTR(PL_curcop);
-               PL_curcop = PL_curcopdb;
-               PL_curcopdb = NULL;
-           }
-           /* Do we need to open block here? XXXX */
-           (void)(*CvXSUB(cv))(aTHX_ cv);
-
-           /* Enforce some sanity in scalar context. */
-           if (gimme == G_SCALAR && ++markix != PL_stack_sp - PL_stack_base ) {
-               if (markix > PL_stack_sp - PL_stack_base)
-                   *(PL_stack_base + markix) = &PL_sv_undef;
-               else
-                   *(PL_stack_base + markix) = *PL_stack_sp;
-               PL_stack_sp = PL_stack_base + markix;
-           }
-       }
-       LEAVE;
-       return NORMAL;
-    }
-    else {
+    if (!(CvXSUB(cv))) {
+       /* This path taken at least 75% of the time   */
        dMARK;
        register I32 items = SP - MARK;
        AV* padlist = CvPADLIST(cv);
@@ -2768,8 +2540,8 @@ try_autoload:
        CvDEPTH(cv)++;
        /* XXX This would be a natural place to set C<PL_compcv = cv> so
         * that eval'' ops within this sub know the correct lexical space.
-        * Owing the speed considerations, we choose to search for the cv
-        * in doeval() instead.
+        * Owing the speed considerations, we choose instead to search for
+        * the cv using find_runcv() when calling doeval().
         */
        if (CvDEPTH(cv) < 2)
            (void)SvREFCNT_inc(cv);
@@ -2777,24 +2549,8 @@ try_autoload:
            PERL_STACK_OVERFLOW_CHECK();
            pad_push(padlist, CvDEPTH(cv), 1);
        }
-#ifdef USE_5005THREADS
-       if (!hasargs) {
-           AV* av = (AV*)PAD_SVl(0);
-
-           items = AvFILLp(av) + 1;
-           if (items) {
-               /* Mark is at the end of the stack. */
-               EXTEND(SP, items);
-               Copy(AvARRAY(av), SP + 1, items, SV*);
-               SP += items;
-               PUTBACK ;               
-           }
-       }
-#endif /* USE_5005THREADS */           
        PAD_SET_CUR(padlist, CvDEPTH(cv));
-#ifndef USE_5005THREADS
        if (hasargs)
-#endif /* USE_5005THREADS */
        {
            AV* av;
            SV** ary;
@@ -2811,10 +2567,8 @@ try_autoload:
                AvREAL_off(av);
                AvREIFY_on(av);
            }
-#ifndef USE_5005THREADS
            cx->blk_sub.savearray = GvAV(PL_defgv);
            GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
-#endif /* USE_5005THREADS */
            CX_CURPAD_SAVE(cx->blk_sub);
            cx->blk_sub.argarray = av;
            ++MARK;
@@ -2854,6 +2608,105 @@ try_autoload:
 #endif
        RETURNOP(CvSTART(cv));
     }
+    else {
+#ifdef PERL_XSUB_OLDSTYLE
+       if (CvOLDSTYLE(cv)) {
+           I32 (*fp3)(int,int,int);
+           dMARK;
+           register I32 items = SP - MARK;
+                                       /* We dont worry to copy from @_. */
+           while (SP > mark) {
+               SP[1] = SP[0];
+               SP--;
+           }
+           PL_stack_sp = mark + 1;
+           fp3 = (I32(*)(int,int,int))CvXSUB(cv);
+           items = (*fp3)(CvXSUBANY(cv).any_i32,
+                          MARK - PL_stack_base + 1,
+                          items);
+           PL_stack_sp = PL_stack_base + items;
+       }
+       else
+#endif /* PERL_XSUB_OLDSTYLE */
+       {
+           I32 markix = TOPMARK;
+
+           PUTBACK;
+
+           if (!hasargs) {
+               /* Need to copy @_ to stack. Alternative may be to
+                * switch stack to @_, and copy return values
+                * back. This would allow popping @_ in XSUB, e.g.. XXXX */
+               AV* av;
+               I32 items;
+               av = GvAV(PL_defgv);
+               items = AvFILLp(av) + 1;   /* @_ is not tieable */
+
+               if (items) {
+                   /* Mark is at the end of the stack. */
+                   EXTEND(SP, items);
+                   Copy(AvARRAY(av), SP + 1, items, SV*);
+                   SP += items;
+                   PUTBACK ;           
+               }
+           }
+           /* We assume first XSUB in &DB::sub is the called one. */
+           if (PL_curcopdb) {
+               SAVEVPTR(PL_curcop);
+               PL_curcop = PL_curcopdb;
+               PL_curcopdb = NULL;
+           }
+           /* Do we need to open block here? XXXX */
+           (void)(*CvXSUB(cv))(aTHX_ cv);
+
+           /* Enforce some sanity in scalar context. */
+           if (gimme == G_SCALAR && ++markix != PL_stack_sp - PL_stack_base ) {
+               if (markix > PL_stack_sp - PL_stack_base)
+                   *(PL_stack_base + markix) = &PL_sv_undef;
+               else
+                   *(PL_stack_base + markix) = *PL_stack_sp;
+               PL_stack_sp = PL_stack_base + markix;
+           }
+       }
+       LEAVE;
+       return NORMAL;
+    }
+
+    assert (0); /* Cannot get here.  */
+    /* This is deliberately moved here as spaghetti code to keep it out of the
+       hot path.  */
+    {
+       GV* autogv;
+       SV* sub_name;
+
+      fooey:
+       /* anonymous or undef'd function leaves us no recourse */
+       if (CvANON(cv) || !(gv = CvGV(cv)))
+           DIE(aTHX_ "Undefined subroutine called");
+
+       /* autoloaded stub? */
+       if (cv != GvCV(gv)) {
+           cv = GvCV(gv);
+       }
+       /* should call AUTOLOAD now? */
+       else {
+try_autoload:
+           if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
+                                  FALSE)))
+           {
+               cv = GvCV(autogv);
+           }
+           /* sorry */
+           else {
+               sub_name = sv_newmortal();
+               gv_efullname3(sub_name, gv, Nullch);
+               DIE(aTHX_ "Undefined subroutine &%"SVf" called", sub_name);
+           }
+       }
+       if (!cv)
+           DIE(aTHX_ "Not a CODE reference");
+       goto retry;
+    }
 }
 
 void
@@ -2864,8 +2717,8 @@ Perl_sub_crush_depth(pTHX_ CV *cv)
     else {
        SV* tmpstr = sv_newmortal();
        gv_efullname3(tmpstr, CvGV(cv), Nullch);
-       Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on subroutine \"%s\"",
-               SvPVX(tmpstr));
+       Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on subroutine \"%"SVf"\"",
+               tmpstr);
     }
 }
 
@@ -2881,7 +2734,7 @@ PP(pp_aelem)
     SV *sv;
 
     if (SvROK(elemsv) && !SvGAMAGIC(elemsv) && ckWARN(WARN_MISC))
-       Perl_warner(aTHX_ packWARN(WARN_MISC), "Use of reference \"%s\" as array index", SvPV_nolen(elemsv));
+       Perl_warner(aTHX_ packWARN(WARN_MISC), "Use of reference \"%"SVf"\" as array index", elemsv);
     if (elem > 0)
        elem -= PL_curcop->cop_arybase;
     if (SvTYPE(av) != SVt_PVAV)
@@ -2982,6 +2835,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
     char* name;
     STRLEN namelen;
     char* packname = 0;
+    SV *packsv = Nullsv;
     STRLEN packlen;
 
     name = SvPV(meth, namelen);
@@ -3017,6 +2871,8 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
            }
            /* assume it's a package name */
            stash = gv_stashpvn(packname, packlen, FALSE);
+           if (!stash)
+               packsv = sv;
            goto fetch;
        }
        /* it _is_ a filehandle name -- replace with a reference */
@@ -3049,7 +2905,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
        }
     }
 
-    gv = gv_fetchmethod(stash, name);
+    gv = gv_fetchmethod(stash ? stash : (HV*)packsv, name);
 
     if (!gv) {
        /* This code tries to figure out just what went wrong with
@@ -3096,22 +2952,3 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
     }
     return isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv;
 }
-
-#ifdef USE_5005THREADS
-static void
-unset_cvowner(pTHX_ void *cvarg)
-{
-    register CV* cv = (CV *) cvarg;
-
-    DEBUG_S((PerlIO_printf(Perl_debug_log, "%p unsetting CvOWNER of %p:%s\n",
-                          thr, cv, SvPEEK((SV*)cv))));
-    MUTEX_LOCK(CvMUTEXP(cv));
-    DEBUG_S(if (CvDEPTH(cv) != 0)
-               PerlIO_printf(Perl_debug_log, "depth %ld != 0\n",
-                             CvDEPTH(cv)));
-    assert(thr == CvOWNER(cv));
-    CvOWNER(cv) = 0;
-    MUTEX_UNLOCK(CvMUTEXP(cv));
-    SvREFCNT_dec(cv);
-}
-#endif /* USE_5005THREADS */