This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
In Perl_sv_del_backref(), don't panic if tsv is already freed.
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index 93462a7..f03f475 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1610,13 +1610,16 @@ Perl_sv_setuv(pTHX_ register SV *const sv, const UV u)
 {
     PERL_ARGS_ASSERT_SV_SETUV;
 
-    /* With these two if statements:
+    /* With the if statement to ensure that integers are stored as IVs whenever
+       possible:
        u=1.49  s=0.52  cu=72.49  cs=10.64  scripts=270  tests=20865
 
        without
        u=1.35  s=0.47  cu=73.45  cs=11.43  scripts=270  tests=20865
 
-       If you wish to remove them, please benchmark to see what the effect is
+       If you wish to remove the following if statement, so that this routine
+       (and its callers) always return UVs, please benchmark to see what the
+       effect is. Modern CPUs may be different. Or may not :-)
     */
     if (u <= (UV)IV_MAX) {
        sv_setiv(sv, (IV)u);
@@ -1776,10 +1779,12 @@ S_not_a_number(pTHX_ SV *const sv)
 
     if (PL_op)
        Perl_warner(aTHX_ packWARN(WARN_NUMERIC),
+                   /* diag_listed_as: Argument "%s" isn't numeric%s */
                    "Argument \"%s\" isn't numeric in %s", pv,
                    OP_DESC(PL_op));
     else
        Perl_warner(aTHX_ packWARN(WARN_NUMERIC),
+                   /* diag_listed_as: Argument "%s" isn't numeric%s */
                    "Argument \"%s\" isn't numeric", pv);
 }
 
@@ -2807,7 +2812,10 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags
                if (!referent) {
                    len = 7;
                    retval = buffer = savepvn("NULLREF", len);
-               } else if (SvTYPE(referent) == SVt_REGEXP) {
+               } else if (SvTYPE(referent) == SVt_REGEXP && (
+                             !(PL_curcop->cop_hints & HINT_NO_AMAGIC)
+                          || amagic_is_enabled(string_amg)
+                         )) {
                    REGEXP * const re = (REGEXP *)MUTABLE_PTR(referent);
                    I32 seen_evals = 0;
 
@@ -3024,11 +3032,16 @@ Usually accessed via the C<SvPVbyte> macro.
 */
 
 char *
-Perl_sv_2pvbyte(pTHX_ register SV *const sv, STRLEN *const lp)
+Perl_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *const lp)
 {
     PERL_ARGS_ASSERT_SV_2PVBYTE;
 
-    SvGETMAGIC(sv);
+    if ((SvTHINKFIRST(sv) && !SvIsCOW(sv)) || isGV_with_GP(sv)) {
+       SV *sv2 = sv_newmortal();
+       sv_copypv(sv2,sv);
+       sv = sv2;
+    }
+    else SvGETMAGIC(sv);
     sv_utf8_downgrade(sv,0);
     return lp ? SvPV_nomg(sv,*lp) : SvPV_nomg_nolen(sv);
 }
@@ -3045,12 +3058,16 @@ Usually accessed via the C<SvPVutf8> macro.
 */
 
 char *
-Perl_sv_2pvutf8(pTHX_ register SV *const sv, STRLEN *const lp)
+Perl_sv_2pvutf8(pTHX_ register SV *sv, STRLEN *const lp)
 {
     PERL_ARGS_ASSERT_SV_2PVUTF8;
 
+    if ((SvTHINKFIRST(sv) && !SvIsCOW(sv)) || isGV_with_GP(sv))
+       sv = sv_mortalcopy(sv);
     sv_utf8_upgrade(sv);
-    return lp ? SvPV(sv,*lp) : SvPV_nolen(sv);
+    if (SvGMAGICAL(sv)) SvFLAGS(sv) &= ~SVf_POK;
+    assert(SvPOKp(sv));
+    return lp ? SvPV_nomg(sv,*lp) : SvPV_nomg_nolen(sv);
 }
 
 
@@ -3138,7 +3155,8 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>.
 Converts the PV of an SV to its UTF-8-encoded form.
 Forces the SV to string form if it is not already.
 Always sets the SvUTF8 flag to avoid future validity checks even
-if all the bytes are invariant in UTF-8. If C<flags> has C<SV_GMAGIC> bit set,
+if all the bytes are invariant in UTF-8.
+If C<flags> has C<SV_GMAGIC> bit set,
 will C<mg_get> on C<sv> if appropriate, else not.
 Returns the number of bytes in the converted string
 C<sv_utf8_upgrade> and
@@ -3518,11 +3536,8 @@ Perl_sv_utf8_encode(pTHX_ register SV *const sv)
 {
     PERL_ARGS_ASSERT_SV_UTF8_ENCODE;
 
-    if (SvIsCOW(sv)) {
-        sv_force_normal_flags(sv, 0);
-    }
     if (SvREADONLY(sv)) {
-       Perl_croak_no_modify(aTHX);
+       sv_force_normal_flags(sv, 0);
     }
     (void) sv_utf8_upgrade(sv);
     SvUTF8_off(sv);
@@ -3559,7 +3574,7 @@ Perl_sv_utf8_decode(pTHX_ register SV *const sv)
          * we want to make sure everything inside is valid utf8 first.
          */
         c = start = (const U8 *) SvPVX_const(sv);
-       if (!is_utf8_string(c, SvCUR(sv)+1))
+       if (!is_utf8_string(c, SvCUR(sv)))
            return FALSE;
         e = (const U8 *) SvEND(sv);
         while (c < e) {
@@ -3645,7 +3660,7 @@ S_glob_assign_glob(pTHX_ SV *const dstr, SV *const sstr, const int dtype)
            }
            SvUPGRADE(dstr, SVt_PVGV);
            (void)SvOK_off(dstr);
-           /* We have to turn this on here (even though we turn it off
+           /* We have to turn this on hereeven though we turn it off
               below, as GvSTASH will fail an assertion otherwise. */
            isGV_with_GP_on(dstr);
        }
@@ -3949,7 +3964,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags)
     if ( SvVOK(dstr) )
     {
        /* need to nuke the magic */
-       mg_free(dstr);
+       sv_unmagic(dstr, PERL_MAGIC_vstring);
     }
 
     /* There's a lot of redundancy below but we're going for speed here */
@@ -4044,6 +4059,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags)
        {
        const char * const type = sv_reftype(sstr,0);
        if (PL_op)
+           /* diag_listed_as: Bizarre copy of %s */
            Perl_croak(aTHX_ "Bizarre copy of %s in %s", type, OP_DESC(PL_op));
        else
            Perl_croak(aTHX_ "Bizarre copy of %s", type);
@@ -4097,6 +4113,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags)
     } else if (dtype == SVt_PVAV || dtype == SVt_PVHV) {
        const char * const type = sv_reftype(dstr,0);
        if (PL_op)
+           /* diag_listed_as: Cannot copy to %s */
            Perl_croak(aTHX_ "Cannot copy to %s in %s", type, OP_DESC(PL_op));
        else
            Perl_croak(aTHX_ "Cannot copy to %s", type);
@@ -4473,7 +4490,8 @@ Perl_sv_setpvn(pTHX_ register SV *const sv, register const char *const ptr, regi
         /* len is STRLEN which is unsigned, need to copy to signed */
        const IV iv = len;
        if (iv < 0)
-           Perl_croak(aTHX_ "panic: sv_setpvn called with negative strlen");
+           Perl_croak(aTHX_ "panic: sv_setpvn called with negative strlen %"
+                      IVdf, iv);
     }
     SvUPGRADE(sv, SVt_PV);
 
@@ -4583,8 +4601,10 @@ Perl_sv_sethek(pTHX_ register SV *const sv, const HEK *const hek)
             return;
        }
         {
+           SV_CHECK_THINKFIRST_COW_DROP(sv);
            SvUPGRADE(sv, SVt_PV);
-           sv_usepvn_flags(sv, (char *)HEK_KEY(share_hek_hek(hek)), HEK_LEN(hek), SV_HAS_TRAILING_NUL);
+           SvPV_set(sv,(char *)HEK_KEY(share_hek_hek(hek)));
+           SvCUR_set(sv, HEK_LEN(hek));
            SvLEN_set(sv, 0);
            SvREADONLY_on(sv);
            SvFAKE_on(sv);
@@ -4604,7 +4624,9 @@ Perl_sv_sethek(pTHX_ register SV *const sv, const HEK *const hek)
 Tells an SV to use C<ptr> to find its string value.  Normally the
 string is stored inside the SV but sv_usepvn allows the SV to use an
 outside string.  The C<ptr> should point to memory that was allocated
-by C<malloc>.  The string length, C<len>, must be supplied.  By default
+by C<malloc>.  It must be the start of a mallocked block
+of memory, and not a pointer to the middle of it.  The
+string length, C<len>, must be supplied.  By default
 this function will realloc (i.e. move) the memory pointed to by C<ptr>,
 so that pointer should not be freed or used by the programmer after
 giving it to sv_usepvn, and neither should any pointers from "behind"
@@ -4787,7 +4809,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *const sv, const U32 flags)
     }
 #else
     if (SvREADONLY(sv)) {
-       if (SvFAKE(sv) && !isGV_with_GP(sv)) {
+       if (SvIsCOW(sv)) {
            const char * const pvx = SvPVX_const(sv);
            const STRLEN len = SvCUR(sv);
            SvFAKE_off(sv);
@@ -4907,7 +4929,7 @@ Perl_sv_chop(pTHX_ register SV *const sv, register const char *const ptr)
            Move(pvx,SvPVX(sv),len,char);
            *SvEND(sv) = '\0';
        }
-       SvFLAGS(sv) |= SVf_OOK;
+       SvOOK_on(sv);
        old_delta = 0;
     } else {
        SvOOK_offset(sv, old_delta);
@@ -5299,9 +5321,8 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how,
 #endif
     if (SvREADONLY(sv)) {
        if (
-           /* its okay to attach magic to shared strings; the subsequent
-            * upgrade to PVMG will unshare the string */
-           !(SvFAKE(sv) && SvTYPE(sv) < SVt_PVMG)
+           /* its okay to attach magic to shared strings */
+           !SvIsCOW(sv)
 
            && IN_PERL_RUNTIME
            && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how)
@@ -5550,14 +5571,48 @@ Perl_sv_del_backref(pTHX_ SV *const tsv, SV *const sv)
        if (SvOOK(tsv))
            svp = (SV**)Perl_hv_backreferences_p(aTHX_ MUTABLE_HV(tsv));
     }
+    else if (SvIS_FREED(tsv) && PL_phase == PERL_PHASE_DESTRUCT) {
+       /* It's possible for the the last (strong) reference to tsv to have
+          become freed *before* the last thing holding a weak reference.
+          If both survive longer than the backreferences array, then when
+          the referent's reference count drops to 0 and it is freed, it's
+          not able to chase the backreferences, so they aren't NULLed.
+
+          For example, a CV holds a weak reference to its stash. If both the
+          CV and the stash survive longer than the backreferences array,
+          and the CV gets picked for the SvBREAK() treatment first,
+          *and* it turns out that the stash is only being kept alive because
+          of an our variable in the pad of the CV, then midway during CV
+          destruction the stash gets freed, but CvSTASH() isn't set to NULL.
+          It ends up pointing to the freed HV. Hence it's chased in here, and
+          if this block wasn't here, it would hit the !svp panic just below.
+
+          I don't believe that "better" destruction ordering is going to help
+          here - during global destruction there's always going to be the
+          chance that something goes out of order. We've tried to make it
+          foolproof before, and it only resulted in evolutionary pressure on
+          fools. Which made us look foolish for our hubris. :-(
+       */
+       return;
+    }
     else {
        MAGIC *const mg
            = SvMAGICAL(tsv) ? mg_find(tsv, PERL_MAGIC_backref) : NULL;
        svp =  mg ? &(mg->mg_obj) : NULL;
     }
 
-    if (!svp || !*svp)
-       Perl_croak(aTHX_ "panic: del_backref");
+    if (!svp)
+       Perl_croak(aTHX_ "panic: del_backref, svp=0");
+    if (!*svp) {
+       /* It's possible that sv is being freed recursively part way through the
+          freeing of tsv. If this happens, the backreferences array of tsv has
+          already been freed, and so svp will be NULL. If this is the case,
+          we should not panic. Instead, nothing needs doing, so return.  */
+       if (PL_phase == PERL_PHASE_DESTRUCT && SvREFCNT(tsv) == 0)
+           return;
+       Perl_croak(aTHX_ "panic: del_backref, *svp=%p phase=%s refcnt=%" UVuf,
+                  *svp, PL_phase_names[PL_phase], (UV)SvREFCNT(tsv));
+    }
 
     if (SvTYPE(*svp) == SVt_PVAV) {
 #ifdef DEBUGGING
@@ -5609,10 +5664,13 @@ Perl_sv_del_backref(pTHX_ SV *const tsv, SV *const sv)
        assert(count ==1);
        AvFILLp(av) = fill-1;
     }
+    else if (SvIS_FREED(*svp) && PL_phase == PERL_PHASE_DESTRUCT) {
+       /* freed AV; skip */
+    }
     else {
        /* optimisation: only a single backref, stored directly */
        if (*svp != sv)
-           Perl_croak(aTHX_ "panic: del_backref");
+           Perl_croak(aTHX_ "panic: del_backref, *svp=%p, sv=%p", *svp, sv);
        *svp = NULL;
     }
 
@@ -5736,7 +5794,7 @@ Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN l
     PERL_ARGS_ASSERT_SV_INSERT_FLAGS;
 
     if (!bigstr)
-       Perl_croak(aTHX_ "Can't modify non-existent substring");
+       Perl_croak(aTHX_ "Can't modify nonexistent substring");
     SvPV_force_flags(bigstr, curlen, flags);
     (void)SvPOK_only_UTF8(bigstr);
     if (offset + len > curlen) {
@@ -5772,7 +5830,8 @@ Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN l
     bigend = big + SvCUR(bigstr);
 
     if (midend > bigend)
-       Perl_croak(aTHX_ "panic: sv_insert");
+       Perl_croak(aTHX_ "panic: sv_insert, midend=%p, bigend=%p",
+                  midend, bigend);
 
     if (mid - big > bigend - midend) { /* faster to shorten from end */
        if (littlelen) {
@@ -6017,6 +6076,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
            Safefree(IoTOP_NAME(sv));
            Safefree(IoFMT_NAME(sv));
            Safefree(IoBOTTOM_NAME(sv));
+           if ((const GV *)sv == PL_statgv)
+               PL_statgv = NULL;
            goto freescalar;
        case SVt_REGEXP:
            /* FIXME for plugins */
@@ -6112,8 +6173,11 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
            /* FIXME. There are probably more unreferenced pointers to SVs
             * in the interpreter struct that we should check and tidy in
             * a similar fashion to this:  */
+           /* See also S_sv_unglob, which does the same thing. */
            if ((const GV *)sv == PL_last_in_gv)
                PL_last_in_gv = NULL;
+           else if ((const GV *)sv == PL_statgv)
+               PL_statgv = NULL;
        case SVt_PVMG:
        case SVt_PVNV:
        case SVt_PVIV:
@@ -6163,7 +6227,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                     && !(SvTYPE(sv) == SVt_PVIO
                     && !(IoFLAGS(sv) & IOf_FAKE_DIRP)))
                Safefree(SvPVX_mutable(sv));
-           else if (SvPVX_const(sv) && SvREADONLY(sv) && SvFAKE(sv)) {
+           else if (SvPVX_const(sv) && SvIsCOW(sv)) {
                unshare_hek(SvSHARED_HEK_FROM_PV(SvPVX_const(sv)));
                SvFAKE_off(sv);
            }
@@ -6450,7 +6514,7 @@ Perl_sv_free2(pTHX_ SV *const sv)
 /*
 =for apidoc sv_len
 
-Returns the length of the string in the SV. Handles magic and type
+Returns the length of the string in the SV.  Handles magic and type
 coercion.  See also C<SvCUR>, which gives raw access to the xpv_cur slot.
 
 =cut
@@ -6717,7 +6781,8 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
 Converts the value pointed to by offsetp from a count of UTF-8 chars from
 the start of the string, to a count of the equivalent number of bytes; if
 lenp is non-zero, it does the same to lenp, but this time starting from
-the offset, rather than from the start of the string. Handles type coercion.
+the offset, rather than from the start
+of the string.  Handles type coercion.
 I<flags> is passed to C<SvPV_flags>, and usually should be
 C<SV_GMAGIC|SV_CONST_RETURN> to handle magic.
 
@@ -6773,7 +6838,7 @@ Perl_sv_pos_u2b_flags(pTHX_ SV *const sv, STRLEN uoffset, STRLEN *const lenp,
 Converts the value pointed to by offsetp from a count of UTF-8 chars from
 the start of the string, to a count of the equivalent number of bytes; if
 lenp is non-zero, it does the same to lenp, but this time starting from
-the offset, rather than from the start of the string. Handles magic and
+the offset, rather than from the start of the string.  Handles magic and
 type coercion.
 
 Use C<sv_pos_u2b_flags> in preference, which correctly handles strings longer
@@ -7049,7 +7114,8 @@ Perl_sv_pos_b2u(pTHX_ register SV *const sv, I32 *const offsetp)
     s = (const U8*)SvPV_const(sv, blen);
 
     if (blen < byte)
-       Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset");
+       Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%"UVuf
+                  ", byte=%"UVuf, (UV)blen, (UV)byte);
 
     send = s + byte;
 
@@ -7945,6 +8011,7 @@ Perl_sv_inc_nomg(pTHX_ register SV *const sv)
        const NV was = SvNVX(sv);
        if (NV_OVERFLOWS_INTEGERS_AT &&
            was >= NV_OVERFLOWS_INTEGERS_AT) {
+           /* diag_listed_as: Lost precision when %s %f by 1 */
            Perl_ck_warner(aTHX_ packWARN(WARN_IMPRECISION),
                           "Lost precision when incrementing %" NVff " by 1",
                           was);
@@ -8129,6 +8196,7 @@ Perl_sv_dec_nomg(pTHX_ register SV *const sv)
            const NV was = SvNVX(sv);
            if (NV_OVERFLOWS_INTEGERS_AT &&
                was <= -NV_OVERFLOWS_INTEGERS_AT) {
+               /* diag_listed_as: Lost precision when %s %f by 1 */
                Perl_ck_warner(aTHX_ packWARN(WARN_IMPRECISION),
                               "Lost precision when decrementing %" NVff " by 1",
                               was);
@@ -8300,7 +8368,7 @@ Perl_newSVpvn_flags(pTHX_ const char *const s, const STRLEN len, const U32 flags
 Marks an existing SV as mortal.  The SV will be destroyed "soon", either
 by an explicit call to FREETMPS, or by an implicit call at places such as
 statement boundaries.  SvTEMP() is turned on which means that the SV's
-string buffer can be "stolen" if this SV is copied. See also C<sv_newmortal>
+string buffer can be "stolen" if this SV is copied.  See also C<sv_newmortal>
 and C<sv_mortalcopy>.
 
 =cut
@@ -8343,22 +8411,24 @@ Perl_newSVpv(pTHX_ const char *const s, const STRLEN len)
 /*
 =for apidoc newSVpvn
 
-Creates a new SV and copies a string into it.  The reference count for the
-SV is set to 1.  Note that if C<len> is zero, Perl will create a zero length
-string.  You are responsible for ensuring that the source string is at least
-C<len> bytes long.  If the C<s> argument is NULL the new SV will be undefined.
+Creates a new SV and copies a buffer into it, which may contain NUL characters
+(C<\0>) and other binary data.  The reference count for the SV is set to 1.
+Note that if C<len> is zero, Perl will create a zero length (Perl) string.  You
+are responsible for ensuring that the source buffer is at least
+C<len> bytes long.  If the C<buffer> argument is NULL the new SV will be
+undefined.
 
 =cut
 */
 
 SV *
-Perl_newSVpvn(pTHX_ const char *const s, const STRLEN len)
+Perl_newSVpvn(pTHX_ const char *const buffer, const STRLEN len)
 {
     dVAR;
     register SV *sv;
 
     new_SV(sv);
-    sv_setpvn(sv,s,len);
+    sv_setpvn(sv,buffer,len);
     return sv;
 }
 
@@ -8441,7 +8511,7 @@ Creates a new SV with its SvPVX_const pointing to a shared string in the string
 table.  If the string does not already exist in the table, it is
 created first.  Turns on READONLY and FAKE.  If the C<hash> parameter
 is non-zero, that value is used; otherwise the hash is computed.
-The string's hash can be later be retrieved from the SV
+The string's hash can later be retrieved from the SV
 with the C<SvSHARED_HASH()> macro.  The idea here is
 that as the string table is used for shared hash keys these strings will have
 SvPVX_const == HeKEY and hash lookup will avoid string compare.
@@ -9474,7 +9544,7 @@ S_sv_unglob(pTHX_ SV *const sv, U32 flags)
     dVAR;
     void *xpvmg;
     HV *stash;
-    SV * const temp = sv_newmortal();
+    SV * const temp = flags & SV_COW_DROP_PV ? NULL : sv_newmortal();
 
     PERL_ARGS_ASSERT_SV_UNGLOB;
 
@@ -9514,6 +9584,11 @@ S_sv_unglob(pTHX_ SV *const sv, U32 flags)
        set operation as merely an internal storage change.  */
     if (flags & SV_COW_DROP_PV) SvOK_off(sv);
     else sv_setsv_flags(sv, temp, 0);
+
+    if ((const GV *)sv == PL_last_in_gv)
+       PL_last_in_gv = NULL;
+    else if ((const GV *)sv == PL_statgv)
+       PL_statgv = NULL;
 }
 
 /*
@@ -10351,7 +10426,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
                 * back into v-string notation and then let the
                 * vectorize happen normally
                 */
-               if (sv_derived_from(vecsv, "version") && SvROK(vecsv)) {
+               if (sv_isobject(vecsv) && sv_derived_from(vecsv, "version")) {
                    char *version = savesvpv(vecsv);
                    if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) {
                        Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
@@ -10986,7 +11061,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
                }
            }
            else
-               sv_setuv_mg(argsv, (UV)i);
+               sv_setuv_mg(argsv, has_utf8 ? (UV)sv_len_utf8(sv) : (UV)i);
            continue;   /* not "break" */
 
            /* UNKNOWN */
@@ -11124,7 +11199,7 @@ the main function, perl_clone().
 
 The foo_dup() functions make an exact copy of an existing foo thingy.
 During the course of a cloning, a hash table is used to map old addresses
-to new addresses. The table is created and manipulated with the
+to new addresses.  The table is created and manipulated with the
 ptr_table_* functions.
 
 =cut
@@ -11314,7 +11389,7 @@ Perl_dirp_dup(pTHX_ DIR *const dp, CLONE_PARAMS *const param)
     register const Direntry_t *dirent;
     char smallbuf[256];
     char *name = NULL;
-    STRLEN len = -1;
+    STRLEN len = 0;
     long pos;
 #endif
 
@@ -11798,6 +11873,27 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                return dstr;
            }
         }
+       else if (SvTYPE(sstr) == SVt_PVGV && !SvFAKE(sstr)) {
+           HV *stash = GvSTASH(sstr);
+           const HEK * hvname;
+           if (stash && (hvname = HvNAME_HEK(stash))) {
+               /** don't clone GVs if they already exist **/
+               SV **svp;
+               stash = gv_stashpvn(HEK_KEY(hvname), HEK_LEN(hvname),
+                                   HEK_UTF8(hvname) ? SVf_UTF8 : 0);
+               svp = hv_fetch(
+                       stash, GvNAME(sstr),
+                       GvNAMEUTF8(sstr)
+                           ? -GvNAMELEN(sstr)
+                           :  GvNAMELEN(sstr),
+                       0
+                     );
+               if (svp && *svp && SvTYPE(*svp) == SVt_PVGV) {
+                   ptr_table_store(PL_ptr_table, sstr, *svp);
+                   return *svp;
+               }
+           }
+        }
     }
 
     /* create anew and remember what it is */
@@ -12034,8 +12130,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                        const struct xpvhv_aux * const saux = HvAUX(sstr);
                        struct xpvhv_aux * const daux = HvAUX(dstr);
                        /* This flag isn't copied.  */
-                       /* SvOOK_on(hv) attacks the IV flags.  */
-                       SvFLAGS(dstr) |= SVf_OOK;
+                       SvOOK_on(dstr);
 
                        if (saux->xhv_name_count) {
                            HEK ** const sname = saux->xhv_name_u.xhvnameu_names;
@@ -13012,10 +13107,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
     PL_globhook                = proto_perl->Iglobhook;
 
-#ifdef THREADS_HAVE_PIDS
-    PL_ppid            = proto_perl->Ippid;
-#endif
-
     /* swatch cache */
     PL_last_swash_hv   = NULL; /* reinits on demand */
     PL_last_swash_klen = 0;
@@ -13313,7 +13404,56 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_numeric_radix_sv        = sv_dup_inc(proto_perl->Inumeric_radix_sv, param);
 #endif /* !USE_LOCALE_NUMERIC */
 
-    /* utf8 character classes */
+    /* Unicode inversion lists */
+    PL_ASCII           = sv_dup_inc(proto_perl->IASCII, param);
+    PL_Latin1          = sv_dup_inc(proto_perl->ILatin1, param);
+
+    PL_PerlSpace       = sv_dup_inc(proto_perl->IPerlSpace, param);
+    PL_XPerlSpace      = sv_dup_inc(proto_perl->IXPerlSpace, param);
+
+    PL_L1PosixAlnum    = sv_dup_inc(proto_perl->IL1PosixAlnum, param);
+    PL_PosixAlnum      = sv_dup_inc(proto_perl->IPosixAlnum, param);
+
+    PL_L1PosixAlpha    = sv_dup_inc(proto_perl->IL1PosixAlpha, param);
+    PL_PosixAlpha      = sv_dup_inc(proto_perl->IPosixAlpha, param);
+
+    PL_PosixBlank      = sv_dup_inc(proto_perl->IPosixBlank, param);
+    PL_XPosixBlank     = sv_dup_inc(proto_perl->IXPosixBlank, param);
+
+    PL_L1Cased         = sv_dup_inc(proto_perl->IL1Cased, param);
+
+    PL_PosixCntrl      = sv_dup_inc(proto_perl->IPosixCntrl, param);
+    PL_XPosixCntrl     = sv_dup_inc(proto_perl->IXPosixCntrl, param);
+
+    PL_PosixDigit      = sv_dup_inc(proto_perl->IPosixDigit, param);
+
+    PL_L1PosixGraph    = sv_dup_inc(proto_perl->IL1PosixGraph, param);
+    PL_PosixGraph      = sv_dup_inc(proto_perl->IPosixGraph, param);
+
+    PL_L1PosixLower    = sv_dup_inc(proto_perl->IL1PosixLower, param);
+    PL_PosixLower      = sv_dup_inc(proto_perl->IPosixLower, param);
+
+    PL_L1PosixPrint    = sv_dup_inc(proto_perl->IL1PosixPrint, param);
+    PL_PosixPrint      = sv_dup_inc(proto_perl->IPosixPrint, param);
+
+    PL_L1PosixPunct    = sv_dup_inc(proto_perl->IL1PosixPunct, param);
+    PL_PosixPunct      = sv_dup_inc(proto_perl->IPosixPunct, param);
+
+    PL_PosixSpace      = sv_dup_inc(proto_perl->IPosixSpace, param);
+    PL_XPosixSpace     = sv_dup_inc(proto_perl->IXPosixSpace, param);
+
+    PL_L1PosixUpper    = sv_dup_inc(proto_perl->IL1PosixUpper, param);
+    PL_PosixUpper      = sv_dup_inc(proto_perl->IPosixUpper, param);
+
+    PL_L1PosixWord     = sv_dup_inc(proto_perl->IL1PosixWord, param);
+    PL_PosixWord       = sv_dup_inc(proto_perl->IPosixWord, param);
+
+    PL_PosixXDigit     = sv_dup_inc(proto_perl->IPosixXDigit, param);
+    PL_XPosixXDigit    = sv_dup_inc(proto_perl->IXPosixXDigit, param);
+
+    PL_VertSpace       = sv_dup_inc(proto_perl->IVertSpace, param);
+
+    /* utf8 character class swashes */
     PL_utf8_alnum      = sv_dup_inc(proto_perl->Iutf8_alnum, param);
     PL_utf8_alpha      = sv_dup_inc(proto_perl->Iutf8_alpha, param);
     PL_utf8_space      = sv_dup_inc(proto_perl->Iutf8_space, param);
@@ -13345,6 +13485,10 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_utf8_idcont     = sv_dup_inc(proto_perl->Iutf8_idcont, param);
     PL_utf8_xidcont    = sv_dup_inc(proto_perl->Iutf8_xidcont, param);
     PL_utf8_foldable   = sv_dup_inc(proto_perl->Iutf8_foldable, param);
+    PL_utf8_quotemeta  = sv_dup_inc(proto_perl->Iutf8_quotemeta, param);
+    PL_ASCII           = sv_dup_inc(proto_perl->IASCII, param);
+    PL_AboveLatin1     = sv_dup_inc(proto_perl->IAboveLatin1, param);
+    PL_Latin1          = sv_dup_inc(proto_perl->ILatin1, param);
 
 
     if (proto_perl->Ipsig_pend) {
@@ -13669,7 +13813,7 @@ assumed to be octets in that encoding and decoding the input starts
 from the position which (PV + *offset) pointed to.  The dsv will be
 concatenated the decoded UTF-8 string from ssv.  Decoding will terminate
 when the string tstr appears in decoding output or the input ends on
-the PV of the ssv. The value which the offset points will be modified
+the PV of the ssv.  The value which the offset points will be modified
 to the last input position on the ssv.
 
 Returns TRUE if the terminator was found, else returns FALSE.
@@ -13802,7 +13946,7 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
 {
 
     SV * const name = sv_newmortal();
-    if (gv) {
+    if (gv && isGV(gv)) {
        char buffer[2];
        buffer[0] = gvtype;
        buffer[1] = 0;
@@ -13821,10 +13965,12 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
        }
     }
     else {
-       CV * const cv = find_runcv(NULL);
+       CV * const cv = gv ? (CV *)gv : find_runcv(NULL);
        SV *sv;
        AV *av;
 
+       assert(!cv || SvTYPE(cv) == SVt_PVCV);
+
        if (!cv || !CvPADLIST(cv))
            return NULL;
        av = MUTABLE_AV((*av_fetch(CvPADLIST(cv), 0, FALSE)));
@@ -13836,7 +13982,8 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
        SV * const sv = newSV(0);
        *SvPVX(name) = '$';
        Perl_sv_catpvf(aTHX_ name, "{%s}",
-           pv_display(sv,SvPVX_const(keyname), SvCUR(keyname), 0, 32));
+           pv_pretty(sv, SvPVX_const(keyname), SvCUR(keyname), 32, NULL, NULL,
+                   PERL_PV_PRETTY_DUMP | PERL_PV_ESCAPE_UNI_DETECT ));
        SvREFCNT_dec(sv);
     }
     else if (subscript_type == FUV_SUBSCRIPT_ARRAY) {
@@ -14265,8 +14412,13 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
        if (!o)
            break;
 
-       /* if all except one arg are constant, or have no side-effects,
-        * or are optimized away, then it's unambiguous */
+       /* This loop checks all the kid ops, skipping any that cannot pos-
+        * sibly be responsible for the uninitialized value; i.e., defined
+        * constants and ops that return nothing.  If there is only one op
+        * left that is not skipped, then we *know* it is responsible for
+        * the uninitialized value.  If there is more than one op left, we
+        * have to look for an exact match in the while() loop below.
+        */
        o2 = NULL;
        for (kid=o; kid; kid = kid->op_sibling) {
            if (kid) {