This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Reduce false positives for @hsh{$s} and @ary[$s] warnings
[perl5.git] / dump.c
diff --git a/dump.c b/dump.c
index 1283d1d..1aa96ce 100644 (file)
--- a/dump.c
+++ b/dump.c
 #define PERL_IN_DUMP_C
 #include "perl.h"
 #include "regcomp.h"
-#include "proto.h"
-
 
 static const char* const svtypenames[SVt_LAST] = {
     "NULL",
-    "BIND",
     "IV",
     "NV",
     "PV",
+    "INVLIST",
     "PVIV",
     "PVNV",
     "PVMG",
@@ -51,10 +49,10 @@ static const char* const svtypenames[SVt_LAST] = {
 
 static const char* const svshorttypenames[SVt_LAST] = {
     "UNDEF",
-    "BIND",
     "IV",
     "NV",
     "PV",
+    "INVLST",
     "PVIV",
     "PVNV",
     "PVMG",
@@ -232,7 +230,7 @@ using C<is_utf8_string()> to determine if it is Unicode.
 
 If PERL_PV_ESCAPE_ALL is set then all input chars will be output
 using C<\x01F1> style escapes, otherwise if PERL_PV_ESCAPE_NONASCII is set, only
-chars above 127 will be escaped using this style; otherwise, only chars above
+non-ASCII chars will be escaped using this style; otherwise, only chars above
 255 will be so escaped; other non printable chars will use octal or
 common escaped patterns like C<\n>. Otherwise, if PERL_PV_ESCAPE_NOBACKSLASH
 then all chars below 255 will be treated as printable and
@@ -286,7 +284,7 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str,
         
         if ( ( u > 255 )
          || (flags & PERL_PV_ESCAPE_ALL)
-         || (( u > 127 ) && (flags & PERL_PV_ESCAPE_NONASCII)))
+         || (( ! isASCII(u) ) && (flags & PERL_PV_ESCAPE_NONASCII)))
        {
             if (flags & PERL_PV_ESCAPE_FIRSTCHAR) 
                 chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, 
@@ -337,12 +335,12 @@ Perl_pv_escape( pTHX_ SV *dsv, char const * const str,
             sv_catpvn(dsv, octbuf, chsize);
             wrote += chsize;
        } else {
-           /* If PERL_PV_ESCAPE_NOBACKSLASH is set then bytes in the range
-              128-255 can be appended raw to the dsv. If dsv happens to be
+           /* If PERL_PV_ESCAPE_NOBACKSLASH is set then non-ASCII bytes
+              can be appended raw to the dsv. If dsv happens to be
               UTF-8 then we need catpvf to upgrade them for us.
               Or add a new API call sv_catpvc(). Think about that name, and
               how to keep it clear that it's unlike the s of catpvs, which is
-              really an array octets, not a string.  */
+              really an array of octets, not a string.  */
             Perl_sv_catpvf( aTHX_ dsv, "%c", c);
            wrote++;
        }
@@ -457,7 +455,8 @@ Perl_sv_peek(pTHX_ SV *sv)
        sv_catpv(t, "VOID");
        goto finish;
     }
-    else if (sv == (const SV *)0x55555555 || SvTYPE(sv) == 'U') {
+    else if (sv == (const SV *)0x55555555 || ((char)SvTYPE(sv)) == 'U') {
+        /* detect data corruption under memory poisoning */
        sv_catpv(t, "WILD");
        goto finish;
     }
@@ -505,7 +504,7 @@ Perl_sv_peek(pTHX_ SV *sv)
     }
     else if (DEBUG_R_TEST_) {
        int is_tmp = 0;
-       I32 ix;
+       SSize_t ix;
        /* is this SV on the tmps stack? */
        for (ix=PL_tmps_ix; ix>=0; ix--) {
            if (PL_tmps_stack[ix] == sv) {
@@ -561,7 +560,7 @@ Perl_sv_peek(pTHX_ SV *sv)
                Perl_sv_catpvf(aTHX_ t, " [UTF8 \"%s\"]",
                               sv_uni_display(tmp, sv, 6 * SvCUR(sv),
                                              UNI_DISPLAY_QQ));
-           SvREFCNT_dec(tmp);
+           SvREFCNT_dec_NN(tmp);
        }
     }
     else if (SvNOKp(sv)) {
@@ -581,7 +580,7 @@ Perl_sv_peek(pTHX_ SV *sv)
   finish:
     while (unref--)
        sv_catpv(t, ")");
-    if (PL_tainting && SvTAINTED(sv))
+    if (TAINTING_get && SvTAINTED(sv))
        sv_catpv(t, " [tainted]");
     return SvPV_nolen(t);
 }
@@ -625,7 +624,7 @@ Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm)
     if (pm->op_pmflags || (PM_GETRE(pm) && RX_CHECK_SUBSTR(PM_GETRE(pm)))) {
        SV * const tmpsv = pm_description(pm);
        Perl_dump_indent(aTHX_ level, file, "PMFLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX_const(tmpsv) + 1 : "");
-       SvREFCNT_dec(tmpsv);
+       SvREFCNT_dec_NN(tmpsv);
     }
 
     Perl_dump_indent(aTHX_ level-1, file, "}\n");
@@ -664,7 +663,7 @@ S_pm_description(pTHX_ const PMOP *pm)
 #endif
 
     if (regex) {
-        if (RX_EXTFLAGS(regex) & RXf_TAINTED)
+        if (RX_ISTAINTED(regex))
             sv_catpv(desc, ",TAINTED");
         if (RX_CHECK_SUBSTR(regex)) {
             if (!(RX_EXTFLAGS(regex) & RXf_NOSCAN))
@@ -771,14 +770,17 @@ const struct flag_to_name op_exit_names[] = {
     {OPpHUSH_VMSISH, ",HUSH_VMSISH"}
 };
 
+const struct flag_to_name op_sassign_names[] = {
+    {OPpASSIGN_BACKWARDS, ",BACKWARDS"},
+    {OPpASSIGN_CV_TO_GV,  ",CV2GV"}
+};
+
 #define OP_PRIVATE_ONCE(op, flag, name) \
     const struct flag_to_name CAT2(op, _names)[] = {   \
        {(flag), (name)} \
     }
 
-OP_PRIVATE_ONCE(op_aassign, OPpASSIGN_COMMON, ",COMMON");
 OP_PRIVATE_ONCE(op_leavesub, OPpREFCOUNTED, ",REFCOUNTED");
-OP_PRIVATE_ONCE(op_sassign, OPpASSIGN_BACKWARDS, ",BACKWARDS");
 OP_PRIVATE_ONCE(op_repeat, OPpREPEAT_DOLIST, ",DOLIST");
 OP_PRIVATE_ONCE(op_reverse, OPpREVERSE_INPLACE, ",INPLACE");
 OP_PRIVATE_ONCE(op_rv2cv, OPpLVAL_INTRO, ",INTRO");
@@ -788,6 +790,7 @@ OP_PRIVATE_ONCE(op_list, OPpLIST_GUESSED, ",GUESSED");
 OP_PRIVATE_ONCE(op_delete, OPpSLICE, ",SLICE");
 OP_PRIVATE_ONCE(op_exists, OPpEXISTS_SUB, ",EXISTS_SUB");
 OP_PRIVATE_ONCE(op_die, OPpHUSH_VMSISH, ",HUSH_VMSISH");
+OP_PRIVATE_ONCE(op_split, OPpSPLIT_IMPLIM, ",IMPLIM");
 
 struct op_private_by_op {
     U16 op_type;
@@ -800,7 +803,6 @@ const struct op_private_by_op op_private_names[] = {
     {OP_LEAVE, C_ARRAY_LENGTH(op_leavesub_names), op_leavesub_names },
     {OP_LEAVESUBLV, C_ARRAY_LENGTH(op_leavesub_names), op_leavesub_names },
     {OP_LEAVEWRITE, C_ARRAY_LENGTH(op_leavesub_names), op_leavesub_names },
-    {OP_AASSIGN, C_ARRAY_LENGTH(op_aassign_names), op_aassign_names },
     {OP_DIE, C_ARRAY_LENGTH(op_die_names), op_die_names },
     {OP_DELETE, C_ARRAY_LENGTH(op_delete_names), op_delete_names },
     {OP_EXISTS, C_ARRAY_LENGTH(op_exists_names), op_exists_names },
@@ -816,6 +818,7 @@ const struct op_private_by_op op_private_names[] = {
     {OP_CONST, C_ARRAY_LENGTH(op_const_names), op_const_names },
     {OP_SORT, C_ARRAY_LENGTH(op_sort_names), op_sort_names },
     {OP_OPEN, C_ARRAY_LENGTH(op_open_names), op_open_names },
+    {OP_SPLIT, C_ARRAY_LENGTH(op_split_names), op_split_names },
     {OP_BACKTICK, C_ARRAY_LENGTH(op_open_names), op_open_names }
 };
 
@@ -837,6 +840,138 @@ S_op_private_to_names(pTHX_ SV *tmpsv, U32 optype, U32 op_private) {
     return FALSE;
 }
 
+#define DUMP_OP_FLAGS(o,xml,level,file)                                 \
+    if (o->op_flags || o->op_slabbed || o->op_savefree || o->op_static) { \
+        SV * const tmpsv = newSVpvs("");                                \
+        switch (o->op_flags & OPf_WANT) {                               \
+        case OPf_WANT_VOID:                                             \
+            sv_catpv(tmpsv, ",VOID");                                   \
+            break;                                                      \
+        case OPf_WANT_SCALAR:                                           \
+            sv_catpv(tmpsv, ",SCALAR");                                 \
+            break;                                                      \
+        case OPf_WANT_LIST:                                             \
+            sv_catpv(tmpsv, ",LIST");                                   \
+            break;                                                      \
+        default:                                                        \
+            sv_catpv(tmpsv, ",UNKNOWN");                                \
+            break;                                                      \
+        }                                                               \
+        append_flags(tmpsv, o->op_flags, op_flags_names);               \
+        if (o->op_slabbed)  sv_catpvs(tmpsv, ",SLABBED");               \
+        if (o->op_savefree) sv_catpvs(tmpsv, ",SAVEFREE");              \
+        if (o->op_static)   sv_catpvs(tmpsv, ",STATIC");                \
+        if (o->op_folded)   sv_catpvs(tmpsv, ",FOLDED");                \
+        if (!xml)                                                        \
+            Perl_dump_indent(aTHX_ level, file, "FLAGS = (%s)\n",       \
+                            SvCUR(tmpsv) ? SvPVX_const(tmpsv) + 1 : "");\
+        else                                                            \
+            PerlIO_printf(file, " flags=\"%s\"",                        \
+                          SvCUR(tmpsv) ? SvPVX(tmpsv) + 1 : "");        \
+        SvREFCNT_dec_NN(tmpsv);                                            \
+    }
+
+#if !defined(PERL_MAD)
+# define xmldump_attr1(level, file, pat, arg)
+#else
+# define xmldump_attr1(level, file, pat, arg) \
+       S_xmldump_attr(aTHX_ level, file, pat, arg)
+#endif
+
+#define DUMP_OP_PRIVATE(o,xml,level,file)                               \
+    if (o->op_private) {                                                \
+        U32 optype = o->op_type;                                        \
+        U32 oppriv = o->op_private;                                     \
+        SV * const tmpsv = newSVpvs("");                                \
+       if (PL_opargs[optype] & OA_TARGLEX) {                           \
+           if (oppriv & OPpTARGET_MY)                                  \
+               sv_catpv(tmpsv, ",TARGET_MY");                          \
+       }                                                               \
+       else if (optype == OP_ENTERSUB ||                               \
+                 optype == OP_RV2SV ||                                  \
+                 optype == OP_GVSV ||                                   \
+                 optype == OP_RV2AV ||                                  \
+                 optype == OP_RV2HV ||                                  \
+                 optype == OP_RV2GV ||                                  \
+                 optype == OP_AELEM ||                                  \
+                 optype == OP_HELEM )                                   \
+        {                                                               \
+            if (optype == OP_ENTERSUB) {                                \
+                append_flags(tmpsv, oppriv, op_entersub_names);         \
+            }                                                           \
+            else {                                                      \
+                switch (oppriv & OPpDEREF) {                            \
+                case OPpDEREF_SV:                                       \
+                    sv_catpv(tmpsv, ",SV");                             \
+                    break;                                              \
+                case OPpDEREF_AV:                                       \
+                    sv_catpv(tmpsv, ",AV");                             \
+                    break;                                              \
+                case OPpDEREF_HV:                                       \
+                    sv_catpv(tmpsv, ",HV");                             \
+                    break;                                              \
+                }                                                       \
+                if (oppriv & OPpMAYBE_LVSUB)                            \
+                    sv_catpv(tmpsv, ",MAYBE_LVSUB");                    \
+            }                                                           \
+            if (optype == OP_AELEM || optype == OP_HELEM) {             \
+                if (oppriv & OPpLVAL_DEFER)                             \
+                    sv_catpv(tmpsv, ",LVAL_DEFER");                     \
+            }                                                           \
+            else if (optype == OP_RV2HV || optype == OP_PADHV) {        \
+                if (oppriv & OPpMAYBE_TRUEBOOL)                         \
+                    sv_catpvs(tmpsv, ",OPpMAYBE_TRUEBOOL");             \
+                if (oppriv & OPpTRUEBOOL)                               \
+                    sv_catpvs(tmpsv, ",OPpTRUEBOOL");                   \
+            }                                                           \
+            else {                                                      \
+                if (oppriv & HINT_STRICT_REFS)                          \
+                    sv_catpv(tmpsv, ",STRICT_REFS");                    \
+                if (oppriv & OPpOUR_INTRO)                              \
+                    sv_catpv(tmpsv, ",OUR_INTRO");                      \
+            }                                                           \
+        }                                                               \
+       else if (S_op_private_to_names(aTHX_ tmpsv, optype, oppriv)) {  \
+       }                                                               \
+       else if (OP_IS_FILETEST(o->op_type)) {                          \
+            if (oppriv & OPpFT_ACCESS)                                  \
+                sv_catpv(tmpsv, ",FT_ACCESS");                          \
+            if (oppriv & OPpFT_STACKED)                                 \
+                sv_catpv(tmpsv, ",FT_STACKED");                         \
+            if (oppriv & OPpFT_STACKING)                                \
+                sv_catpv(tmpsv, ",FT_STACKING");                        \
+            if (oppriv & OPpFT_AFTER_t)                                 \
+                sv_catpv(tmpsv, ",AFTER_t");                            \
+       }                                                               \
+       else if (o->op_type == OP_AASSIGN) {                            \
+           if (oppriv & OPpASSIGN_COMMON)                              \
+               sv_catpvs(tmpsv, ",COMMON");                            \
+           if (oppriv & OPpMAYBE_LVSUB)                                \
+               sv_catpvs(tmpsv, ",MAYBE_LVSUB");                       \
+       }                                                               \
+       if (o->op_flags & OPf_MOD && oppriv & OPpLVAL_INTRO)            \
+           sv_catpv(tmpsv, ",INTRO");                                  \
+       if (o->op_type == OP_PADRANGE)                                  \
+           Perl_sv_catpvf(aTHX_ tmpsv, ",COUNT=%"UVuf,                 \
+                           (UV)(oppriv & OPpPADRANGE_COUNTMASK));       \
+        if (  (o->op_type == OP_RV2HV || o->op_type == OP_RV2AV ||      \
+               o->op_type == OP_PADAV || o->op_type == OP_PADHV ||      \
+               o->op_type == OP_ASLICE || o->op_type == OP_HSLICE ||    \
+               o->op_type == OP_KVHSLICE || o->op_type == OP_KVASLICE)  \
+           && oppriv & OPpSLICEWARNING  )                               \
+            sv_catpvs(tmpsv, ",SLICEWARNING");                          \
+       if (SvCUR(tmpsv)) {                                             \
+            if (xml)                                                    \
+                xmldump_attr1(level+1, file, "private=\"%s\"", SvPVX(tmpsv)+1); \
+            else                                                        \
+                Perl_dump_indent(aTHX_ level, file, "PRIVATE = (%s)\n", SvPVX_const(tmpsv) + 1); \
+       } else if (!xml)                                                \
+            Perl_dump_indent(aTHX_ level, file, "PRIVATE = (0x%"UVxf")\n", \
+                             (UV)oppriv);                               \
+       SvREFCNT_dec_NN(tmpsv);                                         \
+    }
+
+
 void
 Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o)
 {
@@ -883,93 +1018,9 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o)
 #ifdef DUMPADDR
     Perl_dump_indent(aTHX_ level, file, "ADDR = 0x%"UVxf" => 0x%"UVxf"\n", (UV)o, (UV)o->op_next);
 #endif
-    if (o->op_flags || o->op_slabbed || o->op_savefree) {
-       SV * const tmpsv = newSVpvs("");
-       switch (o->op_flags & OPf_WANT) {
-       case OPf_WANT_VOID:
-           sv_catpv(tmpsv, ",VOID");
-           break;
-       case OPf_WANT_SCALAR:
-           sv_catpv(tmpsv, ",SCALAR");
-           break;
-       case OPf_WANT_LIST:
-           sv_catpv(tmpsv, ",LIST");
-           break;
-       default:
-           sv_catpv(tmpsv, ",UNKNOWN");
-           break;
-       }
-       append_flags(tmpsv, o->op_flags, op_flags_names);
-       if (o->op_slabbed)  sv_catpvs(tmpsv, ",SLABBED");
-       if (o->op_savefree) sv_catpvs(tmpsv, ",SAVEFREE");
-       Perl_dump_indent(aTHX_ level, file, "FLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX_const(tmpsv) + 1 : "");
-       SvREFCNT_dec(tmpsv);
-    }
-    if (o->op_private) {
-       SV * const tmpsv = newSVpvs("");
-       if (PL_opargs[optype] & OA_TARGLEX) {
-           if (o->op_private & OPpTARGET_MY)
-               sv_catpv(tmpsv, ",TARGET_MY");
-       }
-       else if (optype == OP_ENTERSUB ||
-           optype == OP_RV2SV ||
-           optype == OP_GVSV ||
-           optype == OP_RV2AV ||
-           optype == OP_RV2HV ||
-           optype == OP_RV2GV ||
-           optype == OP_AELEM ||
-           optype == OP_HELEM )
-       {
-           if (optype == OP_ENTERSUB) {
-               append_flags(tmpsv, o->op_private, op_entersub_names);
-           }
-           else {
-               switch (o->op_private & OPpDEREF) {
-               case OPpDEREF_SV:
-                   sv_catpv(tmpsv, ",SV");
-                   break;
-               case OPpDEREF_AV:
-                   sv_catpv(tmpsv, ",AV");
-                   break;
-               case OPpDEREF_HV:
-                   sv_catpv(tmpsv, ",HV");
-                   break;
-               }
-               if (o->op_private & OPpMAYBE_LVSUB)
-                   sv_catpv(tmpsv, ",MAYBE_LVSUB");
-           }
 
-           if (optype == OP_AELEM || optype == OP_HELEM) {
-               if (o->op_private & OPpLVAL_DEFER)
-                   sv_catpv(tmpsv, ",LVAL_DEFER");
-           }
-           else if (optype == OP_RV2HV || optype == OP_PADHV) {
-             if (o->op_private & OpMAYBE_TRUEBOOL)
-               sv_catpvs(tmpsv, ",OpMAYBE_TRUEBOOL");
-             if (o->op_private & OPpTRUEBOOL)
-               sv_catpvs(tmpsv, ",OPpTRUEBOOL");
-           }
-           else {
-               if (o->op_private & HINT_STRICT_REFS)
-                   sv_catpv(tmpsv, ",STRICT_REFS");
-               if (o->op_private & OPpOUR_INTRO)
-                   sv_catpv(tmpsv, ",OUR_INTRO");
-           }
-       }
-       else if (S_op_private_to_names(aTHX_ tmpsv, optype, o->op_private)) {
-       }
-       else if (PL_check[optype] != Perl_ck_ftst) {
-           if (OP_IS_FILETEST_ACCESS(o->op_type) && o->op_private & OPpFT_ACCESS)
-               sv_catpv(tmpsv, ",FT_ACCESS");
-           if (o->op_private & OPpFT_STACKED)
-               sv_catpv(tmpsv, ",FT_STACKED");
-       }
-       if (o->op_flags & OPf_MOD && o->op_private & OPpLVAL_INTRO)
-           sv_catpv(tmpsv, ",INTRO");
-       if (SvCUR(tmpsv))
-           Perl_dump_indent(aTHX_ level, file, "PRIVATE = (%s)\n", SvPVX_const(tmpsv) + 1);
-       SvREFCNT_dec(tmpsv);
-    }
+    DUMP_OP_FLAGS(o,0,level,file);
+    DUMP_OP_PRIVATE(o,0,level,file);
 
 #ifdef PERL_MAD
     if (PL_madskills && o->op_madprop) {
@@ -1010,7 +1061,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o)
        level--;
        Perl_dump_indent(aTHX_ level, file, "}\n");
 
-       SvREFCNT_dec(tmpsv);
+       SvREFCNT_dec_NN(tmpsv);
     }
 #endif
 
@@ -1217,6 +1268,9 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32
                Perl_dump_indent(aTHX_ level, file, "      DUP\n");
            if (mg->mg_flags & MGf_LOCAL)
                Perl_dump_indent(aTHX_ level, file, "      LOCAL\n");
+           if (mg->mg_type == PERL_MAGIC_regex_global &&
+               mg->mg_flags & MGf_BYTES)
+               Perl_dump_indent(aTHX_ level, file, "      BYTES\n");
         }
        if (mg->mg_obj) {
            Perl_dump_indent(aTHX_ level, file, "    MG_OBJ = 0x%"UVxf"\n",
@@ -1245,7 +1299,7 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32
                if (mg->mg_type != PERL_MAGIC_utf8) {
                    SV * const sv = newSVpvs("");
                    PerlIO_printf(file, " %s", pv_display(sv, mg->mg_ptr, mg->mg_len, 0, pvlim));
-                   SvREFCNT_dec(sv);
+                   SvREFCNT_dec_NN(sv);
                }
             }
            else if (mg->mg_len == HEf_SVKEY) {
@@ -1349,6 +1403,7 @@ const struct flag_to_name second_sv_flags_names[] = {
     {SVf_OOK, "OOK,"},
     {SVf_FAKE, "FAKE,"},
     {SVf_READONLY, "READONLY,"},
+    {SVf_IsCOW, "IsCOW,"},
     {SVf_BREAK, "BREAK,"},
     {SVf_AMAGIC, "OVERLOAD,"},
     {SVp_IOK, "pIOK,"},
@@ -1378,7 +1433,6 @@ const struct flag_to_name hv_flags_names[] = {
     {SVphv_SHAREKEYS, "SHAREKEYS,"},
     {SVphv_LAZYDEL, "LAZYDEL,"},
     {SVphv_HASKFLAGS, "HASKFLAGS,"},
-    {SVphv_REHASH, "REHASH,"},
     {SVphv_CLONEABLE, "CLONEABLE,"}
 };
 
@@ -1408,7 +1462,7 @@ const struct flag_to_name regexp_flags_names[] = {
     {RXf_ANCH_GPOS,       "ANCH_GPOS,"},
     {RXf_GPOS_SEEN,       "GPOS_SEEN,"},
     {RXf_GPOS_FLOAT,      "GPOS_FLOAT,"},
-    {RXf_LOOKBEHIND_SEEN, "LOOKBEHIND_SEEN,"},
+    {RXf_NO_INPLACE_SUBST, "NO_INPLACE_SUBST,"},
     {RXf_EVAL_SEEN,       "EVAL_SEEN,"},
     {RXf_CANY_SEEN,       "CANY_SEEN,"},
     {RXf_NOSCAN,          "NOSCAN,"},
@@ -1470,7 +1524,8 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        if (SvWEAKREF(sv))      sv_catpv(d, "WEAKREF,");
     }
     append_flags(d, flags, second_sv_flags_names);
-    if (flags & SVp_SCREAM && type != SVt_PVHV && !isGV_with_GP(sv)) {
+    if (flags & SVp_SCREAM && type != SVt_PVHV && !isGV_with_GP(sv)
+                          && type != SVt_PVAV) {
        if (SvPCS_IMPORTED(sv))
                                sv_catpv(d, "PCS_IMPORTED,");
        else
@@ -1518,6 +1573,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        if (SvPAD_STATE(sv))    sv_catpv(d, "STATE,");
        goto evaled_or_uv;
     case SVt_PVAV:
+       if (AvPAD_NAMELIST(sv)) sv_catpvs(d, "NAMELIST,");
        break;
     }
     /* SVphv_SHAREKEYS is also 0x20000000 */
@@ -1552,12 +1608,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        PerlIO_printf(file, "%s%s\n", svtypenames[type], s);
 
        if (type ==  SVt_NULL) {
-           SvREFCNT_dec(d);
+           SvREFCNT_dec_NN(d);
            return;
        }
     } else {
        PerlIO_printf(file, "UNKNOWN(0x%"UVxf") %s\n", (UV)type, s);
-       SvREFCNT_dec(d);
+       SvREFCNT_dec_NN(d);
        return;
     }
 
@@ -1611,12 +1667,16 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
     }
 
     if (type < SVt_PV) {
-       SvREFCNT_dec(d);
+       SvREFCNT_dec_NN(d);
        return;
     }
 
-    if (type <= SVt_PVLV && !isGV_with_GP(sv)) {
-       if (SvPVX_const(sv)) {
+    if ((type <= SVt_PVLV && !isGV_with_GP(sv))
+     || (type == SVt_PVIO && IoFLAGS(sv) & IOf_FAKE_DIRP)) {
+       const bool re = isREGEXP(sv);
+       const char * const ptr =
+           re ? RX_WRAPPED((REGEXP*)sv) : SvPVX_const(sv);
+       if (ptr) {
            STRLEN delta;
            if (SvOOK(sv)) {
                SvOOK_offset(sv, delta);
@@ -1625,18 +1685,36 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
            } else {
                delta = 0;
            }
-           Perl_dump_indent(aTHX_ level, file,"  PV = 0x%"UVxf" ", PTR2UV(SvPVX_const(sv)));
+           Perl_dump_indent(aTHX_ level, file,"  PV = 0x%"UVxf" ", PTR2UV(ptr));
            if (SvOOK(sv)) {
                PerlIO_printf(file, "( %s . ) ",
-                             pv_display(d, SvPVX_const(sv) - delta, delta, 0,
+                             pv_display(d, ptr - delta, delta, 0,
                                         pvlim));
            }
-           PerlIO_printf(file, "%s", pv_display(d, SvPVX_const(sv), SvCUR(sv), SvLEN(sv), pvlim));
-           if (SvUTF8(sv)) /* the 6?  \x{....} */
-               PerlIO_printf(file, " [UTF8 \"%s\"]", sv_uni_display(d, sv, 6 * SvCUR(sv), UNI_DISPLAY_QQ));
-           PerlIO_printf(file, "\n");
+            if (type == SVt_INVLIST) {
+               PerlIO_printf(file, "\n");
+                /* 4 blanks indents 2 beyond the PV, etc */
+                _invlist_dump(file, level, "    ", sv);
+            }
+            else {
+                PerlIO_printf(file, "%s", pv_display(d, ptr, SvCUR(sv),
+                                                     re ? 0 : SvLEN(sv),
+                                                     pvlim));
+                if (SvUTF8(sv)) /* the 6?  \x{....} */
+                    PerlIO_printf(file, " [UTF8 \"%s\"]",
+                                         sv_uni_display(d, sv, 6 * SvCUR(sv),
+                                                        UNI_DISPLAY_QQ));
+                PerlIO_printf(file, "\n");
+            }
            Perl_dump_indent(aTHX_ level, file, "  CUR = %"IVdf"\n", (IV)SvCUR(sv));
-           Perl_dump_indent(aTHX_ level, file, "  LEN = %"IVdf"\n", (IV)SvLEN(sv));
+           if (!re)
+               Perl_dump_indent(aTHX_ level, file, "  LEN = %"IVdf"\n",
+                                      (IV)SvLEN(sv));
+#ifdef PERL_NEW_COPY_ON_WRITE
+           if (SvIsCOW(sv) && SvLEN(sv))
+               Perl_dump_indent(aTHX_ level, file, "  COW_REFCNT = %d\n",
+                                      CowREFCNT(sv));
+#endif
        }
        else
            Perl_dump_indent(aTHX_ level, file, "  PV = 0\n");
@@ -1647,6 +1725,9 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
            HV * const ost = SvOURSTASH(sv);
            if (ost)
                do_hv_dump(level, file, "  OURSTASH", ost);
+       } else if (SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv)) {
+           Perl_dump_indent(aTHX_ level, file, "  MAXNAMED = %"UVuf"\n",
+                                  (UV)PadnamelistMAXNAMED(sv));
        } else {
            if (SvMAGIC(sv))
                do_magic_dump(level, file, SvMAGIC(sv), nest+1, maxnest, dumpops, pvlim);
@@ -1655,8 +1736,6 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
            do_hv_dump(level, file, "  STASH", SvSTASH(sv));
 
        if ((type == SVt_PVMG || type == SVt_PVLV) && SvVALID(sv)) {
-           Perl_dump_indent(aTHX_ level, file, "  RARE = %u\n", (U8)BmRARE(sv));
-           Perl_dump_indent(aTHX_ level, file, "  PREVIOUS = %"UVuf"\n", (UV)BmPREVIOUS(sv));
            Perl_dump_indent(aTHX_ level, file, "  USEFUL = %"IVdf"\n", (IV)BmUSEFUL(sv));
        }
     }
@@ -1674,14 +1753,18 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
            PerlIO_putc(file, '\n');
        Perl_dump_indent(aTHX_ level, file, "  FILL = %"IVdf"\n", (IV)AvFILLp(sv));
        Perl_dump_indent(aTHX_ level, file, "  MAX = %"IVdf"\n", (IV)AvMAX(sv));
-       Perl_dump_indent(aTHX_ level, file, "  ARYLEN = 0x%"UVxf"\n", SvMAGIC(sv) ? PTR2UV(AvARYLEN(sv)) : 0);
+       /* arylen is stored in magic, and padnamelists use SvMAGIC for
+          something else. */
+       if (!AvPAD_NAMELIST(sv))
+           Perl_dump_indent(aTHX_ level, file, "  ARYLEN = 0x%"UVxf"\n",
+                                  SvMAGIC(sv) ? PTR2UV(AvARYLEN(sv)) : 0);
        sv_setpvs(d, "");
        if (AvREAL(sv)) sv_catpv(d, ",REAL");
        if (AvREIFY(sv))        sv_catpv(d, ",REIFY");
        Perl_dump_indent(aTHX_ level, file, "  FLAGS = (%s)\n",
                         SvCUR(d) ? SvPVX_const(d) + 1 : "");
        if (nest < maxnest && av_len(MUTABLE_AV(sv)) >= 0) {
-           int count;
+           SSize_t count;
            for (count = 0; count <=  av_len(MUTABLE_AV(sv)) && count < maxnest; count++) {
                SV** const elt = av_fetch(MUTABLE_AV(sv),count,0);
 
@@ -1748,10 +1831,42 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        }
        PerlIO_putc(file, '\n');
        Perl_dump_indent(aTHX_ level, file, "  KEYS = %"IVdf"\n", (IV)HvUSEDKEYS(sv));
-       Perl_dump_indent(aTHX_ level, file, "  FILL = %"IVdf"\n", (IV)HvFILL(sv));
+        {
+            STRLEN count = 0;
+            HE **ents = HvARRAY(sv);
+
+            if (ents) {
+                HE *const *const last = ents + HvMAX(sv);
+                count = last + 1 - ents;
+                
+                do {
+                    if (!*ents)
+                        --count;
+                } while (++ents <= last);
+            }
+
+            if (SvOOK(sv)) {
+                struct xpvhv_aux *const aux = HvAUX(sv);
+                Perl_dump_indent(aTHX_ level, file, "  FILL = %"UVuf
+                                 " (cached = %"UVuf")\n",
+                                 (UV)count, (UV)aux->xhv_fill_lazy);
+            } else {
+                Perl_dump_indent(aTHX_ level, file, "  FILL = %"UVuf"\n",
+                                 (UV)count);
+            }
+        }
        Perl_dump_indent(aTHX_ level, file, "  MAX = %"IVdf"\n", (IV)HvMAX(sv));
-       Perl_dump_indent(aTHX_ level, file, "  RITER = %"IVdf"\n", (IV)HvRITER_get(sv));
-       Perl_dump_indent(aTHX_ level, file, "  EITER = 0x%"UVxf"\n", PTR2UV(HvEITER_get(sv)));
+        if (SvOOK(sv)) {
+           Perl_dump_indent(aTHX_ level, file, "  RITER = %"IVdf"\n", (IV)HvRITER_get(sv));
+           Perl_dump_indent(aTHX_ level, file, "  EITER = 0x%"UVxf"\n", PTR2UV(HvEITER_get(sv)));
+#ifdef PERL_HASH_RANDOMIZE_KEYS
+           Perl_dump_indent(aTHX_ level, file, "  RAND = 0x%"UVxf, (UV)HvRAND_get(sv));
+            if (HvRAND_get(sv) != HvLASTRAND_get(sv) && HvRITER_get(sv) != -1 ) {
+                PerlIO_printf(file, " (LAST = 0x%"UVxf")", (UV)HvLASTRAND_get(sv));
+            }
+#endif
+            PerlIO_putc(file, '\n');
+        }
        {
            MAGIC * const mg = mg_find(sv, PERL_MAGIC_symtab);
            if (mg && mg->mg_obj) {
@@ -1857,7 +1972,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                        SV * keysv;
                        const char * keypv;
                        SV * elt;
-               STRLEN len;
+                        STRLEN len;
 
                        if (count-- <= 0) goto DONEHV;
 
@@ -1866,16 +1981,14 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                        keypv = SvPV_const(keysv, len);
                        elt = HeVAL(he);
 
-               Perl_dump_indent(aTHX_ level+1, file, "Elt %s ", pv_display(d, keypv, len, 0, pvlim));
-               if (SvUTF8(keysv))
-                   PerlIO_printf(file, "[UTF8 \"%s\"] ", sv_uni_display(d, keysv, 6 * SvCUR(keysv), UNI_DISPLAY_QQ));
+                        Perl_dump_indent(aTHX_ level+1, file, "Elt %s ", pv_display(d, keypv, len, 0, pvlim));
+                        if (SvUTF8(keysv))
+                            PerlIO_printf(file, "[UTF8 \"%s\"] ", sv_uni_display(d, keysv, 6 * SvCUR(keysv), UNI_DISPLAY_QQ));
                        if (HvEITER_get(hv) == he)
                            PerlIO_printf(file, "[CURRENT] ");
-               if (HeKREHASH(he))
-                   PerlIO_printf(file, "[REHASH] ");
-                       PerlIO_printf(file, "HASH = 0x%"UVxf"\n", (UV) hash);
-               do_sv_dump(level+1, file, elt, nest+1, maxnest, dumpops, pvlim);
-           }
+                        PerlIO_printf(file, "HASH = 0x%"UVxf"\n", (UV) hash);
+                        do_sv_dump(level+1, file, elt, nest+1, maxnest, dumpops, pvlim);
+                    }
                }
              DONEHV:;
            }
@@ -1924,7 +2037,10 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                                 (IV)CvXSUBANY(sv).any_i32);
            }
        }
-       do_gvgv_dump(level, file, "  GVGV::GV", CvGV(sv));
+       if (CvNAMED(sv))
+           Perl_dump_indent(aTHX_ level, file, "  NAME = \"%s\"\n",
+                                  HEK_KEY(CvNAME_HEK((CV *)sv)));
+       else do_gvgv_dump(level, file, "  GVGV::GV", CvGV(sv));
        Perl_dump_indent(aTHX_ level, file, "  FILE = \"%s\"\n", CvFILE(sv));
        Perl_dump_indent(aTHX_ level, file, "  DEPTH = %"IVdf"\n", (IV)CvDEPTH(sv));
        Perl_dump_indent(aTHX_ level, file, "  FLAGS = 0x%"UVxf"\n", (UV)CvFLAGS(sv));
@@ -1959,6 +2075,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                do_sv_dump(level+1, file, LvTARG(sv), nest+1, maxnest,
                    dumpops, pvlim);
        }
+       if (isREGEXP(sv)) goto dumpregexp;
        if (!isGV_with_GP(sv))
            break;
        Perl_dump_indent(aTHX_ level, file, "  NAME = \"%s\"\n", GvNAME(sv));
@@ -2027,17 +2144,26 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        Perl_dump_indent(aTHX_ level, file, "  FLAGS = 0x%"UVxf"\n", (UV)IoFLAGS(sv));
        break;
     case SVt_REGEXP:
+      dumpregexp:
        {
-           struct regexp * const r = (struct regexp *)SvANY(sv);
-           flags = RX_EXTFLAGS((REGEXP*)sv);
-           sv_setpv(d,"");
-           append_flags(d, flags, regexp_flags_names);
-           if (*(SvEND(d) - 1) == ',') {
-               SvCUR_set(d, SvCUR(d) - 1);
-               SvPVX(d)[SvCUR(d)] = '\0';
-           }
+           struct regexp * const r = ReANY((REGEXP*)sv);
+#define SV_SET_STRINGIFY_REGEXP_FLAGS(d,flags) STMT_START { \
+            sv_setpv(d,"");                                 \
+            append_flags(d, flags, regexp_flags_names);     \
+            if (SvCUR(d) > 0 && *(SvEND(d) - 1) == ',') {       \
+                SvCUR_set(d, SvCUR(d) - 1);                 \
+                SvPVX(d)[SvCUR(d)] = '\0';                  \
+            }                                               \
+} STMT_END
+            SV_SET_STRINGIFY_REGEXP_FLAGS(d,r->compflags);
+            Perl_dump_indent(aTHX_ level, file, "  COMPFLAGS = 0x%"UVxf" (%s)\n",
+                                (UV)(r->compflags), SvPVX_const(d));
+
+            SV_SET_STRINGIFY_REGEXP_FLAGS(d,r->extflags);
            Perl_dump_indent(aTHX_ level, file, "  EXTFLAGS = 0x%"UVxf" (%s)\n",
-                               (UV)flags, SvPVX_const(d));
+                                (UV)(r->extflags), SvPVX_const(d));
+#undef SV_SET_STRINGIFY_REGEXP_FLAGS
+
            Perl_dump_indent(aTHX_ level, file, "  INTFLAGS = 0x%"UVxf"\n",
                                (UV)(r->intflags));
            Perl_dump_indent(aTHX_ level, file, "  NPARENS = %"UVuf"\n",
@@ -2056,6 +2182,10 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                                (UV)(r->pre_prefix));
            Perl_dump_indent(aTHX_ level, file, "  SUBLEN = %"IVdf"\n",
                                (IV)(r->sublen));
+           Perl_dump_indent(aTHX_ level, file, "  SUBOFFSET = %"IVdf"\n",
+                               (IV)(r->suboffset));
+           Perl_dump_indent(aTHX_ level, file, "  SUBCOFFSET = %"IVdf"\n",
+                               (IV)(r->subcoffset));
            if (r->subbeg)
                Perl_dump_indent(aTHX_ level, file, "  SUBBEG = 0x%"UVxf" %s\n",
                            PTR2UV(r->subbeg),
@@ -2066,6 +2196,9 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                                PTR2UV(r->engine));
            Perl_dump_indent(aTHX_ level, file, "  MOTHER_RE = 0x%"UVxf"\n",
                                PTR2UV(r->mother_re));
+           if (nest < maxnest && r->mother_re)
+               do_sv_dump(level+1, file, (SV *)r->mother_re, nest+1,
+                          maxnest, dumpops, pvlim);
            Perl_dump_indent(aTHX_ level, file, "  PAREN_NAMES = 0x%"UVxf"\n",
                                PTR2UV(r->paren_names));
            Perl_dump_indent(aTHX_ level, file, "  SUBSTRS = 0x%"UVxf"\n",
@@ -2076,14 +2209,14 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                                PTR2UV(r->offs));
            Perl_dump_indent(aTHX_ level, file, "  QR_ANONCV = 0x%"UVxf"\n",
                                PTR2UV(r->qr_anoncv));
-#ifdef PERL_OLD_COPY_ON_WRITE
+#ifdef PERL_ANY_COW
            Perl_dump_indent(aTHX_ level, file, "  SAVED_COPY = 0x%"UVxf"\n",
                                PTR2UV(r->saved_copy));
 #endif
        }
        break;
     }
-    SvREFCNT_dec(d);
+    SvREFCNT_dec_NN(d);
 }
 
 void
@@ -2110,6 +2243,9 @@ Perl_runops_debug(pTHX)
 
     DEBUG_l(Perl_deb(aTHX_ "Entering new RUNOPS level\n"));
     do {
+#ifdef PERL_TRACE_OPS
+        ++PL_op_exec_cnt[PL_op->op_type];
+#endif
        if (PL_debug) {
            if (PL_watchaddr && (*PL_watchaddr != PL_watchok))
                PerlIO_printf(Perl_debug_log,
@@ -2129,8 +2265,11 @@ Perl_runops_debug(pTHX)
            if (DEBUG_t_TEST_) debop(PL_op);
            if (DEBUG_P_TEST_) debprof(PL_op);
        }
+
+        OP_ENTRY_PROBE(OP_NAME(PL_op));
     } while ((PL_op = PL_op->op_ppaddr(aTHX)));
     DEBUG_l(Perl_deb(aTHX_ "leaving RUNOPS level\n"));
+    PERL_ASYNC_CHECK();
 
     TAINT_NOT;
     return 0;
@@ -2170,30 +2309,50 @@ Perl_debop(pTHX_ const OP *o)
 #endif
            gv_fullname3(sv, cGVOPo_gv, NULL);
            PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen_const(sv));
-           SvREFCNT_dec(sv);
+           SvREFCNT_dec_NN(sv);
        }
        else
            PerlIO_printf(Perl_debug_log, "(NULL)");
        break;
+
+    {
+        int count;
+
     case OP_PADSV:
     case OP_PADAV:
     case OP_PADHV:
-       {
+        count = 1;
+        goto dump_padop;
+    case OP_PADRANGE:
+        count = o->op_private & OPpPADRANGE_COUNTMASK;
+    dump_padop:
        /* print the lexical's name */
-       CV * const cv = deb_curcv(cxstack_ix);
-       SV *sv;
-        if (cv) {
-           PADLIST * const padlist = CvPADLIST(cv);
-            PAD * const comppad = *PadlistARRAY(padlist);
-            sv = *av_fetch(comppad, o->op_targ, FALSE);
-        } else
-            sv = NULL;
-        if (sv)
-           PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen_const(sv));
-        else
-           PerlIO_printf(Perl_debug_log, "[%"UVuf"]", (UV)o->op_targ);
-       }
+        {
+            CV * const cv = deb_curcv(cxstack_ix);
+            SV *sv;
+            PAD * comppad = NULL;
+            int i;
+
+            if (cv) {
+                PADLIST * const padlist = CvPADLIST(cv);
+                comppad = *PadlistARRAY(padlist);
+            }
+            PerlIO_printf(Perl_debug_log, "(");
+            for (i = 0; i < count; i++) {
+                if (comppad &&
+                        (sv = *av_fetch(comppad, o->op_targ + i, FALSE)))
+                    PerlIO_printf(Perl_debug_log, "%s", SvPV_nolen_const(sv));
+                else
+                    PerlIO_printf(Perl_debug_log, "[%"UVuf"]",
+                            (UV)o->op_targ+i);
+                if (i < count-1)
+                    PerlIO_printf(Perl_debug_log, ",");
+            }
+            PerlIO_printf(Perl_debug_log, ")");
+        }
         break;
+    }
+
     default:
        break;
     }
@@ -2444,64 +2603,15 @@ Perl_sv_catxmlpvn(pTHX_ SV *dsv, const char *pv, STRLEN len, int utf8)
        else
            c = (*pv & 255);
 
-       switch (c) {
-       case 0x00:
-       case 0x01:
-       case 0x02:
-       case 0x03:
-       case 0x04:
-       case 0x05:
-       case 0x06:
-       case 0x07:
-       case 0x08:
-       case 0x0b:
-       case 0x0c:
-       case 0x0e:
-       case 0x0f:
-       case 0x10:
-       case 0x11:
-       case 0x12:
-       case 0x13:
-       case 0x14:
-       case 0x15:
-       case 0x16:
-       case 0x17:
-       case 0x18:
-       case 0x19:
-       case 0x1a:
-       case 0x1b:
-       case 0x1c:
-       case 0x1d:
-       case 0x1e:
-       case 0x1f:
-       case 0x7f:
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9a:
-       case 0x9b:
-       case 0x9c:
-       case 0x9d:
-       case 0x9e:
-       case 0x9f:
+        if (isCNTRL_L1(c)
+            && c != '\t'
+            && c != '\n'
+            && c != '\r'
+            && c != LATIN1_TO_NATIVE(0x85))
+        {
            Perl_sv_catpvf(aTHX_ dsv, "STUPIDXML(#x%X)", c);
-           break;
+        }
+        else switch (c) {
        case '<':
            sv_catpvs(dsv, "&lt;");
            break;
@@ -2516,7 +2626,7 @@ Perl_sv_catxmlpvn(pTHX_ SV *dsv, const char *pv, STRLEN len, int utf8)
            break;
        default:
            if (c < 0xD800) {
-               if (c < 32 || c > 127) {
+               if (! isPRINT(c)) {
                    Perl_sv_catpvf(aTHX_ dsv, "&#x%X;", c);
                }
                else {
@@ -2559,7 +2669,7 @@ Perl_sv_xmlpeek(pTHX_ SV *sv)
        sv_catpv(t, "VOID=\"\"");
        goto finish;
     }
-    else if (sv == (const SV *)0x55555555 || SvTYPE(sv) == 'U') {
+    else if (sv == (const SV *)0x55555555 || ((char)SvTYPE(sv)) == 'U') {
        sv_catpv(t, "WILD=\"\"");
        goto finish;
     }
@@ -2607,7 +2717,7 @@ Perl_sv_xmlpeek(pTHX_ SV *sv)
     }
     else if (DEBUG_R_TEST_) {
        int is_tmp = 0;
-       I32 ix;
+       SSize_t ix;
        /* is this SV on the tmps stack? */
        for (ix=PL_tmps_ix; ix>=0; ix--) {
            if (PL_tmps_stack[ix] == sv) {
@@ -2669,8 +2779,8 @@ Perl_sv_xmlpeek(pTHX_ SV *sv)
     case SVt_PVGV:
        sv_catpv(t, " GV=\"");
        break;
-    case SVt_BIND:
-       sv_catpv(t, " BIND=\"");
+    case SVt_INVLIST:
+       sv_catpv(t, " DUMMY=\"");
        break;
     case SVt_REGEXP:
        sv_catpv(t, " REGEXP=\"");
@@ -2726,7 +2836,7 @@ Perl_do_pmop_xmldump(pTHX_ I32 level, PerlIO *file, const PMOP *pm)
        sv_catxmlsv(tmpsv, MUTABLE_SV(r));
        Perl_xmldump_indent(aTHX_ level, file, "pre=\"%s\"\n",
             SvPVX(tmpsv));
-       SvREFCNT_dec(tmpsv);
+       SvREFCNT_dec_NN(tmpsv);
        Perl_xmldump_indent(aTHX_ level, file, "when=\"%s\"\n",
             (pm->op_private & OPpRUNTIME) ? "RUN" : "COMP");
     }
@@ -2735,7 +2845,7 @@ Perl_do_pmop_xmldump(pTHX_ I32 level, PerlIO *file, const PMOP *pm)
     if (pm->op_pmflags || (PM_GETRE(pm) && RX_CHECK_SUBSTR(PM_GETRE(pm)))) {
        SV * const tmpsv = pm_description(pm);
        Perl_xmldump_indent(aTHX_ level, file, "pmflags=\"%s\"\n", SvCUR(tmpsv) ? SvPVX(tmpsv) + 1 : "");
-       SvREFCNT_dec(tmpsv);
+       SvREFCNT_dec_NN(tmpsv);
     }
 
     level--;
@@ -2761,6 +2871,7 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o)
 {
     UV      seq;
     int     contents = 0;
+    const OPCODE optype = o->op_type;
 
     PERL_ARGS_ASSERT_DO_OP_XMLDUMP;
 
@@ -2779,7 +2890,7 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o)
        PerlIO_printf(file, "DONE\"");
 
     if (o->op_targ) {
-       if (o->op_type == OP_NULL)
+       if (optype == OP_NULL)
        {
            PerlIO_printf(file, " was=\"%s\"", PL_op_name[o->op_targ]);
            if (o->op_targ == OP_NEXTSTATE)
@@ -2801,201 +2912,11 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o)
 #ifdef DUMPADDR
     PerlIO_printf(file, " addr=\"0x%"UVxf" => 0x%"UVxf"\"", (UV)o, (UV)o->op_next);
 #endif
-    if (o->op_flags) {
-       SV * const tmpsv = newSVpvs("");
-       switch (o->op_flags & OPf_WANT) {
-       case OPf_WANT_VOID:
-           sv_catpv(tmpsv, ",VOID");
-           break;
-       case OPf_WANT_SCALAR:
-           sv_catpv(tmpsv, ",SCALAR");
-           break;
-       case OPf_WANT_LIST:
-           sv_catpv(tmpsv, ",LIST");
-           break;
-       default:
-           sv_catpv(tmpsv, ",UNKNOWN");
-           break;
-       }
-       if (o->op_flags & OPf_KIDS)
-           sv_catpv(tmpsv, ",KIDS");
-       if (o->op_flags & OPf_PARENS)
-           sv_catpv(tmpsv, ",PARENS");
-       if (o->op_flags & OPf_STACKED)
-           sv_catpv(tmpsv, ",STACKED");
-       if (o->op_flags & OPf_REF)
-           sv_catpv(tmpsv, ",REF");
-       if (o->op_flags & OPf_MOD)
-           sv_catpv(tmpsv, ",MOD");
-       if (o->op_flags & OPf_SPECIAL)
-           sv_catpv(tmpsv, ",SPECIAL");
-       PerlIO_printf(file, " flags=\"%s\"", SvCUR(tmpsv) ? SvPVX(tmpsv) + 1 : "");
-       SvREFCNT_dec(tmpsv);
-    }
-    if (o->op_private) {
-       SV * const tmpsv = newSVpvs("");
-       if (PL_opargs[o->op_type] & OA_TARGLEX) {
-           if (o->op_private & OPpTARGET_MY)
-               sv_catpv(tmpsv, ",TARGET_MY");
-       }
-       else if (o->op_type == OP_LEAVESUB ||
-                o->op_type == OP_LEAVE ||
-                o->op_type == OP_LEAVESUBLV ||
-                o->op_type == OP_LEAVEWRITE) {
-           if (o->op_private & OPpREFCOUNTED)
-               sv_catpv(tmpsv, ",REFCOUNTED");
-       }
-        else if (o->op_type == OP_AASSIGN) {
-           if (o->op_private & OPpASSIGN_COMMON)
-               sv_catpv(tmpsv, ",COMMON");
-       }
-       else if (o->op_type == OP_SASSIGN) {
-           if (o->op_private & OPpASSIGN_BACKWARDS)
-               sv_catpv(tmpsv, ",BACKWARDS");
-       }
-       else if (o->op_type == OP_TRANS) {
-           if (o->op_private & OPpTRANS_SQUASH)
-               sv_catpv(tmpsv, ",SQUASH");
-           if (o->op_private & OPpTRANS_DELETE)
-               sv_catpv(tmpsv, ",DELETE");
-           if (o->op_private & OPpTRANS_COMPLEMENT)
-               sv_catpv(tmpsv, ",COMPLEMENT");
-           if (o->op_private & OPpTRANS_IDENTICAL)
-               sv_catpv(tmpsv, ",IDENTICAL");
-           if (o->op_private & OPpTRANS_GROWS)
-               sv_catpv(tmpsv, ",GROWS");
-       }
-       else if (o->op_type == OP_REPEAT) {
-           if (o->op_private & OPpREPEAT_DOLIST)
-               sv_catpv(tmpsv, ",DOLIST");
-       }
-       else if (o->op_type == OP_ENTERSUB ||
-                o->op_type == OP_RV2SV ||
-                o->op_type == OP_GVSV ||
-                o->op_type == OP_RV2AV ||
-                o->op_type == OP_RV2HV ||
-                o->op_type == OP_RV2GV ||
-                o->op_type == OP_AELEM ||
-                o->op_type == OP_HELEM )
-       {
-           if (o->op_type == OP_ENTERSUB) {
-               if (o->op_private & OPpENTERSUB_AMPER)
-                   sv_catpv(tmpsv, ",AMPER");
-               if (o->op_private & OPpENTERSUB_DB)
-                   sv_catpv(tmpsv, ",DB");
-               if (o->op_private & OPpENTERSUB_HASTARG)
-                   sv_catpv(tmpsv, ",HASTARG");
-               if (o->op_private & OPpENTERSUB_NOPAREN)
-                   sv_catpv(tmpsv, ",NOPAREN");
-               if (o->op_private & OPpENTERSUB_INARGS)
-                   sv_catpv(tmpsv, ",INARGS");
-           }
-           else {
-               switch (o->op_private & OPpDEREF) {
-           case OPpDEREF_SV:
-               sv_catpv(tmpsv, ",SV");
-               break;
-           case OPpDEREF_AV:
-               sv_catpv(tmpsv, ",AV");
-               break;
-           case OPpDEREF_HV:
-               sv_catpv(tmpsv, ",HV");
-               break;
-           }
-               if (o->op_private & OPpMAYBE_LVSUB)
-                   sv_catpv(tmpsv, ",MAYBE_LVSUB");
-           }
-           if (o->op_type == OP_AELEM || o->op_type == OP_HELEM) {
-               if (o->op_private & OPpLVAL_DEFER)
-                   sv_catpv(tmpsv, ",LVAL_DEFER");
-           }
-           else {
-               if (o->op_private & HINT_STRICT_REFS)
-                   sv_catpv(tmpsv, ",STRICT_REFS");
-               if (o->op_private & OPpOUR_INTRO)
-                   sv_catpv(tmpsv, ",OUR_INTRO");
-           }
-       }
-       else if (o->op_type == OP_CONST) {
-           if (o->op_private & OPpCONST_BARE)
-               sv_catpv(tmpsv, ",BARE");
-           if (o->op_private & OPpCONST_STRICT)
-               sv_catpv(tmpsv, ",STRICT");
-           if (o->op_private & OPpCONST_ENTERED)
-               sv_catpv(tmpsv, ",ENTERED");
-           if (o->op_private & OPpCONST_FOLDED)
-               sv_catpv(tmpsv, ",FOLDED");
-       }
-       else if (o->op_type == OP_FLIP) {
-           if (o->op_private & OPpFLIP_LINENUM)
-               sv_catpv(tmpsv, ",LINENUM");
-       }
-       else if (o->op_type == OP_FLOP) {
-           if (o->op_private & OPpFLIP_LINENUM)
-               sv_catpv(tmpsv, ",LINENUM");
-       }
-       else if (o->op_type == OP_RV2CV) {
-           if (o->op_private & OPpLVAL_INTRO)
-               sv_catpv(tmpsv, ",INTRO");
-       }
-       else if (o->op_type == OP_GV) {
-           if (o->op_private & OPpEARLY_CV)
-               sv_catpv(tmpsv, ",EARLY_CV");
-       }
-       else if (o->op_type == OP_LIST) {
-           if (o->op_private & OPpLIST_GUESSED)
-               sv_catpv(tmpsv, ",GUESSED");
-       }
-       else if (o->op_type == OP_DELETE) {
-           if (o->op_private & OPpSLICE)
-               sv_catpv(tmpsv, ",SLICE");
-       }
-       else if (o->op_type == OP_EXISTS) {
-           if (o->op_private & OPpEXISTS_SUB)
-               sv_catpv(tmpsv, ",EXISTS_SUB");
-       }
-       else if (o->op_type == OP_SORT) {
-           if (o->op_private & OPpSORT_NUMERIC)
-               sv_catpv(tmpsv, ",NUMERIC");
-           if (o->op_private & OPpSORT_INTEGER)
-               sv_catpv(tmpsv, ",INTEGER");
-           if (o->op_private & OPpSORT_REVERSE)
-               sv_catpv(tmpsv, ",REVERSE");
-       }
-       else if (o->op_type == OP_OPEN || o->op_type == OP_BACKTICK) {
-           if (o->op_private & OPpOPEN_IN_RAW)
-               sv_catpv(tmpsv, ",IN_RAW");
-           if (o->op_private & OPpOPEN_IN_CRLF)
-               sv_catpv(tmpsv, ",IN_CRLF");
-           if (o->op_private & OPpOPEN_OUT_RAW)
-               sv_catpv(tmpsv, ",OUT_RAW");
-           if (o->op_private & OPpOPEN_OUT_CRLF)
-               sv_catpv(tmpsv, ",OUT_CRLF");
-       }
-       else if (o->op_type == OP_EXIT) {
-           if (o->op_private & OPpEXIT_VMSISH)
-               sv_catpv(tmpsv, ",EXIT_VMSISH");
-           if (o->op_private & OPpHUSH_VMSISH)
-               sv_catpv(tmpsv, ",HUSH_VMSISH");
-       }
-       else if (o->op_type == OP_DIE) {
-           if (o->op_private & OPpHUSH_VMSISH)
-               sv_catpv(tmpsv, ",HUSH_VMSISH");
-       }
-       else if (PL_check[o->op_type] != Perl_ck_ftst) {
-           if (OP_IS_FILETEST_ACCESS(o->op_type) && o->op_private & OPpFT_ACCESS)
-               sv_catpv(tmpsv, ",FT_ACCESS");
-           if (o->op_private & OPpFT_STACKED)
-               sv_catpv(tmpsv, ",FT_STACKED");
-       }
-       if (o->op_flags & OPf_MOD && o->op_private & OPpLVAL_INTRO)
-           sv_catpv(tmpsv, ",INTRO");
-       if (SvCUR(tmpsv))
-           S_xmldump_attr(aTHX_ level, file, "private=\"%s\"", SvPVX(tmpsv) + 1);
-       SvREFCNT_dec(tmpsv);
-    }
 
-    switch (o->op_type) {
+    DUMP_OP_FLAGS(o,1,0,file);
+    DUMP_OP_PRIVATE(o,1,0,file);
+
+    switch (optype) {
     case OP_AELEMFAST:
        if (o->op_flags & OPf_SPECIAL) {
            break;
@@ -3147,10 +3068,10 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o)
        level--;
        Perl_xmldump_indent(aTHX_ level, file, "</madprops>\n");
 
-       SvREFCNT_dec(tmpsv);
+       SvREFCNT_dec_NN(tmpsv);
     }
 
-    switch (o->op_type) {
+    switch (optype) {
     case OP_PUSHRE:
     case OP_MATCH:
     case OP_QR: