This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Move all the FBM data fields from the table into a struct xbm_s which
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index eabc2bf..60c606a 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -48,11 +48,12 @@ typedef enum {
        SVt_IV,         /* 1 */
        SVt_NV,         /* 2 */
        SVt_RV,         /* 3 */
-       SVt_PV,         /* 4 */
-       SVt_PVIV,       /* 5 */
-       SVt_PVNV,       /* 6 */
-       SVt_PVMG,       /* 7 */
-       SVt_PVBM,       /* 8 */
+       SVt_BIND,       /* 4 */
+       SVt_PV,         /* 5 */
+       SVt_PVIV,       /* 6 */
+       SVt_PVNV,       /* 7 */
+       SVt_PVMG,       /* 8 */
+       /* PVBM was here, before BIND replaced it.  */
        SVt_PVGV,       /* 9 */
        SVt_PVLV,       /* 10 */
        SVt_PVAV,       /* 11 */
@@ -63,6 +64,13 @@ typedef enum {
        SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
+#ifndef PERL_CORE
+/* Although Fast Boyer Moore tables are now being stored in PVGVs, for most
+   purposes eternal code wanting to consider PVBM probably needs to think of
+   PVMG instead.  */
+#  define SVt_PVBM     SVt_PVMG
+#endif
+
 /* There is collusion here with sv_clear - sv_clear exits early for SVt_NULL
    and SVt_IV, so never reaches the clause at the end that uses
    sv_type_details->body_size to determine whether to call safefree(). Hence
@@ -275,52 +283,56 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1))
 
-#define SVf_IOK                0x00000100      /* has valid public integer value */
-#define SVf_NOK                0x00000200      /* has valid public numeric value */
-#define SVf_POK                0x00000400      /* has valid public pointer value */
-#define SVf_ROK                0x00000800      /* has a valid reference pointer */
-
-#define SVp_IOK                0x00001000      /* has valid non-public integer value */
-#define SVp_NOK                0x00002000      /* has valid non-public numeric value */
-#define SVp_POK                0x00004000      /* has valid non-public pointer value */
-#define SVp_SCREAM     0x00008000      /* has been studied? */
-#define SVphv_CLONEABLE        0x00008000      /* PVHV (stashes) clone its objects */
-
-#define SVs_PADSTALE   0x00010000      /* lexical has gone out of scope */
-#define SVpad_STATE    0x00010000      /* pad name is a "state" var */
-#define SVs_PADTMP     0x00020000      /* in use as tmp */
-#define SVpad_TYPED    0x00020000      /* pad name is a Typed Lexical */
-#define SVs_PADMY      0x00040000      /* in use a "my" variable */
-#define SVpad_OUR      0x00040000      /* pad name is "our" instead of "my" */
-#define SVs_TEMP       0x00080000      /* string is stealable? */
-#define SVs_OBJECT     0x00100000      /* is "blessed" */
-#define SVs_GMG                0x00200000      /* has magical get method */
-#define SVs_SMG                0x00400000      /* has magical set method */
-#define SVs_RMG                0x00800000      /* has random magical methods */
-
-#define SVf_FAKE       0x01000000      /* 0: glob or lexical is just a copy
-                                          1: SV head arena wasn't malloc()ed
-                                          2: in conjunction with SVf_READONLY
-                                             marks a shared hash key scalar
-                                             (SvLEN == 0) or a copy on write
-                                             string (SvLEN != 0) [SvIsCOW(sv)]
-                                          3: For PVCV, whether CvUNIQUE(cv)
-                                             refers to an eval or once only
-                                             [CvEVAL(cv), CvSPECIAL(cv)]
-                                          4: Whether the regexp pointer is in
-                                             fact an offset [SvREPADTMP(sv)]
-                                          5: On a pad name SV, that slot in the
-                                             frame AV is a REFCNT'ed reference
-                                             to a lexical from "outside". */
-#define SVphv_REHASH   SVf_FAKE        /* 6: On a PVHV, hash values are being
-                                             recalculated */
-#define SVf_OOK                0x02000000      /* has valid offset value
-                                          For a PVHV this means that a
-                                          hv_aux struct is present after the
-                                          main array  */
-#define SVf_BREAK      0x04000000      /* refcnt is artificially low - used
-                                        * by SV's in final arena  cleanup */
-#define SVf_READONLY   0x08000000      /* may not be modified */
+#define SVf_IOK                0x00000100  /* has valid public integer value */
+#define SVf_NOK                0x00000200  /* has valid public numeric value */
+#define SVf_POK                0x00000400  /* has valid public pointer value */
+#define SVf_ROK                0x00000800  /* has a valid reference pointer */
+
+#define SVp_IOK                0x00001000  /* has valid non-public integer value */
+#define SVp_NOK                0x00002000  /* has valid non-public numeric value */
+#define SVp_POK                0x00004000  /* has valid non-public pointer value */
+#define SVp_SCREAM     0x00008000  /* has been studied? */
+#define SVphv_CLONEABLE        SVp_SCREAM  /* PVHV (stashes) clone its objects */
+#define SVpgv_GP       SVp_SCREAM  /* GV has a valid GP */
+#define SVprv_PCS_IMPORTED  SVp_SCREAM  /* RV is a proxy for a constant
+                                      subroutine in another package. Set the
+                                      CvIMPORTED_CV_ON() if it needs to be
+                                      expanded to a real GV */
+
+#define SVs_PADSTALE   0x00010000  /* lexical has gone out of scope */
+#define SVpad_STATE    0x00010000  /* pad name is a "state" var */
+#define SVs_PADTMP     0x00020000  /* in use as tmp */
+#define SVpad_TYPED    0x00020000  /* pad name is a Typed Lexical */
+#define SVs_PADMY      0x00040000  /* in use a "my" variable */
+#define SVpad_OUR      0x00040000  /* pad name is "our" instead of "my" */
+#define SVs_TEMP       0x00080000  /* string is stealable? */
+#define SVs_OBJECT     0x00100000  /* is "blessed" */
+#define SVs_GMG                0x00200000  /* has magical get method */
+#define SVs_SMG                0x00400000  /* has magical set method */
+#define SVs_RMG                0x00800000  /* has random magical methods */
+
+#define SVf_FAKE       0x01000000  /* 0: glob or lexical is just a copy
+                                      1: SV head arena wasn't malloc()ed
+                                      2: in conjunction with SVf_READONLY
+                                         marks a shared hash key scalar
+                                         (SvLEN == 0) or a copy on write
+                                         string (SvLEN != 0) [SvIsCOW(sv)]
+                                      3: For PVCV, whether CvUNIQUE(cv)
+                                         refers to an eval or once only
+                                         [CvEVAL(cv), CvSPECIAL(cv)]
+                                      4: Whether the regexp pointer is in
+                                         fact an offset [SvREPADTMP(sv)]
+                                      5: On a pad name SV, that slot in the
+                                         frame AV is a REFCNT'ed reference
+                                         to a lexical from "outside". */
+#define SVphv_REHASH   SVf_FAKE    /* 6: On a PVHV, hash values are being
+                                         recalculated */
+#define SVf_OOK                0x02000000  /* has valid offset value. For a PVHV this
+                                      means that a hv_aux struct is present
+                                      after the main array */
+#define SVf_BREAK      0x04000000  /* refcnt is artificially low - used by
+                                      SV's in final arena  cleanup */
+#define SVf_READONLY   0x08000000  /* may not be modified */
 
 
 
@@ -328,51 +340,64 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE)
 
 #define SVf_OK         (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
-                        SVp_IOK|SVp_NOK|SVp_POK|SVp_SCREAM)
+                        SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP)
 
 #define PRIVSHIFT 4    /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
 
-#define SVf_AMAGIC     0x10000000      /* has magical overloaded methods */
-#define SVf_UTF8        0x20000000      /* SvPV is UTF-8 encoded */
+#define SVf_AMAGIC     0x10000000  /* has magical overloaded methods */
+#define SVf_UTF8        0x20000000  /* SvPV is UTF-8 encoded
+                                      This is also set on RVs whose overloaded
+                                      stringification is UTF-8. This might
+                                      only happen as a side effect of SvPV() */
+                                          
 /* Ensure this value does not clash with the GV_ADD* flags in gv.h */
 
 /* Some private flags. */
 
 /* PVHV */
-#define SVphv_SHAREKEYS 0x20000000     /* PVHV
-                                          keys live on shared string table */
-/* PVNV, PVMG, PVGV, presumably only inside pads */
-#define SVpad_NAME     0x40000000      /* This SV is a name in the PAD, so
-                                          SVpad_TYPED, SVpad_OUR and
-                                          SVpad_STATE apply */
+#define SVphv_SHAREKEYS 0x20000000  /* PVHV keys live on shared string table */
+/* PVNV, PVMG, presumably only inside pads */
+#define SVpad_NAME     0x40000000  /* This SV is a name in the PAD, so
+                                      SVpad_TYPED, SVpad_OUR and SVpad_STATE
+                                      apply */
 /* PVAV */
-#define SVpav_REAL     0x40000000      /* free old entries */
+#define SVpav_REAL     0x40000000  /* free old entries */
 /* PVHV */
-#define SVphv_LAZYDEL  0x40000000      /* entry in xhv_eiter must be deleted */
-/* PVBM */
-#define SVpbm_TAIL     0x40000000
+#define SVphv_LAZYDEL  0x40000000  /* entry in xhv_eiter must be deleted */
+/* This is only set true on a PVGV when it's playing "PVBM", but is tested for
+   on any regular scalar (anything <= PVLV) */
+#define SVpbm_VALID    0x40000000
 /* ??? */
-#define SVrepl_EVAL    0x40000000      /* Replacement part of s///e */
+#define SVrepl_EVAL    0x40000000  /* Replacement part of s///e */
 
 /* IV, PVIV, PVNV, PVMG, PVGV and (I assume) PVLV  */
 /* Presumably IVs aren't stored in pads */
-#define SVf_IVisUV     0x80000000      /* use XPVUV instead of XPVIV */
+#define SVf_IVisUV     0x80000000  /* use XPVUV instead of XPVIV */
 /* PVAV */
-#define SVpav_REIFY    0x80000000      /* can become real */
+#define SVpav_REIFY    0x80000000  /* can become real */
 /* PVHV */
-#define SVphv_HASKFLAGS        0x80000000      /* keys have flag byte after hash */
+#define SVphv_HASKFLAGS        0x80000000  /* keys have flag byte after hash */
 /* PVFM */
-#define SVpfm_COMPILED 0x80000000      /* FORMLINE is compiled */
-/* PVBM */
-#define SVpbm_VALID    0x80000000
+#define SVpfm_COMPILED 0x80000000  /* FORMLINE is compiled */
+/* PVGV when SVpbm_VALID is true */
+#define SVpbm_TAIL     0x80000000
 /* RV upwards. However, SVf_ROK and SVp_IOK are exclusive  */
-#define SVprv_WEAKREF   0x80000000      /* Weak reference */
+#define SVprv_WEAKREF   0x80000000  /* Weak reference */
 
 
 struct xpv {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -391,6 +416,15 @@ struct xpviv {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -425,6 +459,15 @@ struct xpvuv {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -442,6 +485,15 @@ struct xpvnv {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -459,6 +511,15 @@ struct xpvmg {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -480,6 +541,15 @@ struct xpvlv {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -503,10 +573,21 @@ struct xpvlv {
                                 * y=alem/helem/iter t=tie T=tied HE */
 };
 
+/* This structure works in 3 ways - regular scalar, GV with GP, or fast
+   Boyer-Moore.  */
 struct xpvgv {
     union {
        NV      xnv_nv;
        HV *    xgv_stash;      /* The stash of this GV */
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* xgv_flags */
     STRLEN     xpv_len;        /* 0 */
@@ -514,7 +595,7 @@ struct xpvgv {
        IV      xivu_iv;
        UV      xivu_uv;
        void *  xivu_p1;
-       I32     xivu_i32;
+       I32     xivu_i32;       /* is this constant pattern being useful? */
        HEK *   xivu_namehek;   /* GvNAME */
     }          xiv_u;
     union {
@@ -525,31 +606,6 @@ struct xpvgv {
 
 };
 
-struct xpvbm {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
-    union {
-       MAGIC*  xmg_magic;      /* linked list of magicalness */
-       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
-    } xmg_u;
-    HV*                xmg_stash;      /* class package */
-
-    I32                xbm_useful;     /* is this constant pattern being useful? */
-    U16                xbm_previous;   /* how many characters in string before rare? */
-    U8         xbm_rare;       /* rarest character in string */
-};
-
 /* This structure must match XPVCV in cv.h */
 
 typedef U16 cv_flags_t;
@@ -558,6 +614,15 @@ struct xpvfm {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -634,6 +699,15 @@ struct xpvio {
     union {
        NV      xnv_nv;         /* numeric value, if any */
        HV *    xgv_stash;
+       struct {
+           U32 xlow;
+           U32 xhigh;
+       }       xpad_cop_seq;   /* used by pad.c for cop_sequence */
+       struct {
+           U32 xbm_previous;   /* how many characters in string before rare? */
+           U8  xbm_flags;
+           U8  xbm_rare;       /* rarest character in string */
+       }       xbm_s;          /* fields from PVBM */
     }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
@@ -917,6 +991,8 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 /*
 =for apidoc Am|bool|SvUTF8|SV* sv
 Returns a boolean indicating whether the SV contains UTF-8 encoded data.
+Call this after SvPV() in case any call to string overloading updates the
+internal flag.
 
 =for apidoc Am|void|SvUTF8_on|SV *sv
 Turn on the UTF-8 status of an SV (the data is not changed, just the flag).
@@ -1022,6 +1098,11 @@ the scalar's value cannot change unless written to.
 #define SvWEAKREF_on(sv)       (SvFLAGS(sv) |=  (SVf_ROK|SVprv_WEAKREF))
 #define SvWEAKREF_off(sv)      (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_WEAKREF))
 
+#define SvPCS_IMPORTED(sv)     ((SvFLAGS(sv) & (SVf_ROK|SVprv_PCS_IMPORTED)) \
+                                == (SVf_ROK|SVprv_PCS_IMPORTED))
+#define SvPCS_IMPORTED_on(sv)  (SvFLAGS(sv) |=  (SVf_ROK|SVprv_PCS_IMPORTED))
+#define SvPCS_IMPORTED_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_PCS_IMPORTED))
+
 #define SvTHINKFIRST(sv)       (SvFLAGS(sv) & SVf_THINKFIRST)
 
 #define SvPADSTALE(sv)         (SvFLAGS(sv) & SVs_PADSTALE)
@@ -1059,13 +1140,38 @@ the scalar's value cannot change unless written to.
 #define SvEVALED_on(sv)                (SvFLAGS(sv) |= SVrepl_EVAL)
 #define SvEVALED_off(sv)       (SvFLAGS(sv) &= ~SVrepl_EVAL)
 
-#define SvTAIL(sv)             (SvFLAGS(sv) & SVpbm_TAIL)
+#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define SvVALID(sv)          ({ SV *const thwacke = (SV *) (sv);     \
+                                  if (SvFLAGS(thwacke) & SVpbm_VALID)  \
+                                      assert(!isGV_with_GP(thwacke));  \
+                                  (SvFLAGS(thwacke) & SVpbm_VALID);    \
+                               })
+#  define SvVALID_on(sv)       ({ SV *const thwacke = (SV *) (sv);     \
+                                  assert(!isGV_with_GP(thwacke));      \
+                                  (SvFLAGS(thwacke) |= SVpbm_VALID);   \
+                               })
+#  define SvVALID_off(sv)      ({ SV *const thwacke = (SV *) (sv);     \
+                                  assert(!isGV_with_GP(thwacke));      \
+                                  (SvFLAGS(thwacke) &= ~SVpbm_VALID);  \
+                               })
+
+#  define SvTAIL(sv)   ({ SV *const _svi = (SV *) (sv);                \
+                           assert(SvTYPE(_svi) != SVt_PVAV);           \
+                           assert(SvTYPE(_svi) != SVt_PVHV);           \
+                           (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID))    \
+                               == (SVpbm_TAIL|SVpbm_VALID);            \
+                       })
+#else
+#  define SvVALID(sv)          (SvFLAGS(sv) & SVpbm_VALID)
+#  define SvVALID_on(sv)       (SvFLAGS(sv) |= SVpbm_VALID)
+#  define SvVALID_off(sv)      (SvFLAGS(sv) &= ~SVpbm_VALID)
+#  define SvTAIL(sv)       ((SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID))   \
+                            == (SVpbm_TAIL|SVpbm_VALID))
+
+#endif
 #define SvTAIL_on(sv)          (SvFLAGS(sv) |= SVpbm_TAIL)
 #define SvTAIL_off(sv)         (SvFLAGS(sv) &= ~SVpbm_TAIL)
 
-#define SvVALID(sv)            (SvFLAGS(sv) & SVpbm_VALID)
-#define SvVALID_on(sv)         (SvFLAGS(sv) |= SVpbm_VALID)
-#define SvVALID_off(sv)                (SvFLAGS(sv) &= ~SVpbm_VALID)
 
 #ifdef USE_ITHREADS
 /* The following uses the FAKE flag to show that a regex pointer is infact
@@ -1077,15 +1183,34 @@ the scalar's value cannot change unless written to.
 
 #define SvPAD_TYPED(sv) \
        ((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED))
-#define SvPAD_TYPED_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)
 
 #define SvPAD_OUR(sv)  \
        ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))
-#define SvPAD_OUR_on(sv)       (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
 
 #define SvPAD_STATE(sv)        \
        ((SvFLAGS(sv) & (SVpad_NAME|SVpad_STATE)) == (SVpad_NAME|SVpad_STATE))
-#define SvPAD_STATE_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE)
+
+#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define SvPAD_TYPED_on(sv)   ({                                      \
+           SV *const whap = (SV *) (sv);                               \
+           assert(SvTYPE(whap) == SVt_PVMG);                           \
+           (SvFLAGS(whap) |= SVpad_NAME|SVpad_TYPED);                  \
+       })
+#define SvPAD_OUR_on(sv)       ({                                      \
+           SV *const whap = (SV *) (sv);                               \
+           assert(SvTYPE(whap) == SVt_PVMG);                           \
+           (SvFLAGS(whap) |= SVpad_NAME|SVpad_OUR);                    \
+       })
+#define SvPAD_STATE_on(sv)     ({                                      \
+           SV *const whap = (SV *) (sv);                               \
+           assert(SvTYPE(whap) == SVt_PVNV || SvTYPE(whap) == SVt_PVMG); \
+           (SvFLAGS(whap) |= SVpad_NAME|SVpad_STATE);                  \
+       })
+#else
+#  define SvPAD_TYPED_on(sv)   (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)
+#  define SvPAD_OUR_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
+#  define SvPAD_STATE_on(sv)   (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE)
+#endif
 
 #define OURSTASH(sv)   \
        (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)
@@ -1132,7 +1257,7 @@ the scalar's value cannot change unless written to.
 #  if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 /* These get expanded inside other macros that already use a variable _sv  */
 #    define SvPVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) >= SVt_PV);                             \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
@@ -1140,7 +1265,7 @@ the scalar's value cannot change unless written to.
            &((_svi)->sv_u.svu_pv);                                     \
         }))
 #    define SvCUR(sv)                                                  \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) >= SVt_PV);                             \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
@@ -1148,7 +1273,7 @@ the scalar's value cannot change unless written to.
            &(((XPV*) SvANY(_svi))->xpv_cur);                           \
         }))
 #    define SvIVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
@@ -1157,7 +1282,7 @@ the scalar's value cannot change unless written to.
            &(((XPVIV*) SvANY(_svi))->xiv_iv);                          \
         }))
 #    define SvUVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
@@ -1166,7 +1291,7 @@ the scalar's value cannot change unless written to.
            &(((XPVUV*) SvANY(_svi))->xuv_uv);                          \
         }))
 #    define SvNVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
@@ -1176,14 +1301,14 @@ the scalar's value cannot change unless written to.
           &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv);                     \
         }))
 #    define SvMAGIC(sv)                                                        \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) >= SVt_PVMG);                           \
            if(SvTYPE(_svi) == SVt_PVMG)                                \
                assert(!SvPAD_OUR(_svi));                               \
            &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic);                 \
          }))
 #    define SvSTASH(sv)                                                        \
-       (*({ SV *const _svi = (SV *) sv;                                \
+       (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) >= SVt_PVMG);                           \
            &(((XPVMG*) SvANY(_svi))->xmg_stash);                       \
          }))
@@ -1300,9 +1425,47 @@ the scalar's value cannot change unless written to.
                     }                                                  \
                 } STMT_END
 
-#define BmRARE(sv)     ((XPVBM*)  SvANY(sv))->xbm_rare
-#define BmUSEFUL(sv)   ((XPVBM*)  SvANY(sv))->xbm_useful
-#define BmPREVIOUS(sv) ((XPVBM*)  SvANY(sv))->xbm_previous
+
+#define PERL_FBM_TABLE_OFFSET 1        /* Number of bytes between EOS and table */
+
+/* SvPOKp not SvPOK in the assertion because the string can be tainted! eg
+   perl -T -e '/$^X/'
+*/
+#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define BmFLAGS(sv)                                                  \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+               assert(SvTYPE(uggh) == SVt_PVGV);                       \
+               assert(SvVALID(uggh));                                  \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_flags);           \
+        }))
+#  define BmRARE(sv)                                                   \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+               assert(SvTYPE(uggh) == SVt_PVGV);                       \
+               assert(SvVALID(uggh));                                  \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare);            \
+        }))
+#  define BmUSEFUL(sv)                                                 \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+           assert(SvTYPE(uggh) == SVt_PVGV);                           \
+           assert(SvVALID(uggh));                                      \
+           assert(!SvIOK(uggh));                                       \
+           &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32);                  \
+        }))
+#  define BmPREVIOUS(sv)                                               \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+               assert(SvTYPE(uggh) == SVt_PVGV);                       \
+               assert(SvVALID(uggh));                                  \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous);        \
+        }))
+#else
+#  define BmFLAGS(sv)          ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags
+#  define BmRARE(sv)           ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_rare
+#  define BmUSEFUL(sv)         ((XPVGV*) SvANY(sv))->xiv_u.xivu_i32
+#  define BmPREVIOUS(sv)       ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_previous
+
+#endif
+#define BmPREVIOUS_set(sv, val)                                                \
+    STMT_START { BmPREVIOUS(sv) = val; } STMT_END
 
 #define FmLINES(sv)    ((XPVFM*)  SvANY(sv))->xfm_lines
 
@@ -1679,6 +1842,21 @@ Like C<sv_catsv> but doesn't process magic.
 #define SV_MUTABLE_RETURN      64
 #define SV_SMAGIC              128
 #define SV_HAS_TRAILING_NUL    256
+#define SV_COW_SHARED_HASH_KEYS        512
+
+/* The core is safe for this COW optimisation. XS code on CPAN may not be.
+   So only default to doing the COW setup if we're in the core.
+ */
+#ifdef PERL_CORE
+#  ifndef SV_DO_COW_SVSETSV
+#    define SV_DO_COW_SVSETSV  SV_COW_SHARED_HASH_KEYS
+#  endif
+#endif
+
+#ifndef SV_DO_COW_SVSETSV
+#  define SV_DO_COW_SVSETSV    0
+#endif
+
 
 #define sv_unref(sv)           sv_unref_flags(sv, 0)
 #define sv_force_normal(sv)    sv_force_normal_flags(sv, 0)
@@ -1720,8 +1898,9 @@ Like C<sv_catsv> but doesn't process magic.
 #define sv_pvn_force_nomg(sv, lp) sv_pvn_force_flags(sv, lp, 0)
 #define sv_utf8_upgrade_nomg(sv) sv_utf8_upgrade_flags(sv, 0)
 #define sv_catpvn_nomg(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, 0)
-#define sv_setsv(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_GMAGIC)
-#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, 0)
+#define sv_setsv(dsv, ssv) \
+       sv_setsv_flags(dsv, ssv, SV_GMAGIC|SV_DO_COW_SVSETSV)
+#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_DO_COW_SVSETSV)
 #define sv_catsv(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC)
 #define sv_catsv_nomg(dsv, ssv) sv_catsv_flags(dsv, ssv, 0)
 #define sv_catsv_mg(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC|SV_SMAGIC)
@@ -1828,7 +2007,7 @@ Returns a pointer to the character buffer.
 #define SvSetSV_nosteal_and(dst,src,finally) \
        STMT_START {                                    \
            if ((dst) != (src)) {                       \
-               sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL);       \
+               sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL | SV_DO_COW_SVSETSV);   \
                finally;                                \
            }                                           \
        } STMT_END
@@ -1858,8 +2037,21 @@ Returns a pointer to the character buffer.
 /* If I give every macro argument a different name, then there won't be bugs
    where nested macros get confused. Been there, done that.  */
 #define isGV_with_GP(pwadak) \
-       (((SvFLAGS(pwadak) & (SVp_POK|SVp_SCREAM)) == SVp_SCREAM)       \
+       (((SvFLAGS(pwadak) & (SVp_POK|SVpgv_GP)) == SVpgv_GP)   \
        && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV))
+#define isGV_with_GP_on(sv)    STMT_START {                           \
+       assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \
+       assert (!SvPOKp(sv));                                          \
+       assert (!SvIOKp(sv));                                          \
+       (SvFLAGS(sv) |= SVpgv_GP);                                     \
+    } STMT_END
+#define isGV_with_GP_off(sv)   STMT_START {                           \
+       assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \
+       assert (!SvPOKp(sv));                                          \
+       assert (!SvIOKp(sv));                                          \
+       (SvFLAGS(sv) &= ~SVpgv_GP);                                    \
+    } STMT_END
+
 
 #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
 #define SvGROW_mutable(sv,len) \