Move all the FBM data fields from the table into a struct xbm_s which
Nicholas Clark [Thu, 28 Dec 2006 23:35:54 +0000 (23:35 +0000)]
is part of the xnv union.

p4raw-id: //depot/perl@29634

av.h
cv.h
hv.h
sv.h
util.c

diff --git a/av.h b/av.h
index 02a0afa..3dfd39e 100644 (file)
--- a/av.h
+++ b/av.h
@@ -16,6 +16,11 @@ struct xpvav {
            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;
     SSize_t    xav_fill;       /* Index of last element present */
     SSize_t    xav_max;        /* max index for which array has space */
diff --git a/cv.h b/cv.h
index cf71d15..cd0b760 100644 (file)
--- a/cv.h
+++ b/cv.h
@@ -18,6 +18,11 @@ struct xpvcv {
            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 xp_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
diff --git a/hv.h b/hv.h
index dee534d..4a2f053 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -56,6 +56,11 @@ struct xpvhv {
            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     xhv_fill;       /* how full xhv_array currently is */
     STRLEN     xhv_max;        /* subscript of last element of xhv_array */
diff --git a/sv.h b/sv.h
index 7614a6a..60c606a 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -393,6 +393,11 @@ struct xpv {
            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 */
@@ -415,6 +420,11 @@ struct xpviv {
            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 */
@@ -453,6 +463,11 @@ struct xpvuv {
            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 */
@@ -474,6 +489,11 @@ struct xpvnv {
            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 */
@@ -495,6 +515,11 @@ struct xpvmg {
            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 */
@@ -520,6 +545,11 @@ struct xpvlv {
            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 */
@@ -553,6 +583,11 @@ struct xpvgv {
            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 */
@@ -583,6 +618,11 @@ struct xpvfm {
            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 */
@@ -663,6 +703,11 @@ struct xpvio {
            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 */
@@ -1381,32 +1426,23 @@ the scalar's value cannot change unless written to.
                 } STMT_END
 
 
-#define PERL_FBM_TABLE_OFFSET 5        /* Number of bytes between EOS and table */
-#define PERL_FBM_FLAGS_OFFSET_FROM_TABLE -1
-/* how many characters in string before rare? */
-#if (BYTEORDER == 0x4321) || (BYTEORDER == 0x87654321)
-#  define PERL_FBM_PREVIOUS_L_OFFSET_FROM_TABLE -2
-#  define PERL_FBM_PREVIOUS_H_OFFSET_FROM_TABLE -3
-#else
-#  define PERL_FBM_PREVIOUS_H_OFFSET_FROM_TABLE -2
-#  define PERL_FBM_PREVIOUS_L_OFFSET_FROM_TABLE -3
-#endif
-/* rarest character in string */
-#define PERL_FBM_RARE_OFFSET_FROM_TABLE -4
+#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));                                  \
-               assert(SvCUR(uggh) + PERL_FBM_TABLE_OFFSET              \
-                      + PERL_FBM_RARE_OFFSET_FROM_TABLE <= SvLEN(uggh)); \
-           assert(SvPOKp(uggh));                                       \
-           (U8*)(SvEND(uggh)                                           \
-                 + PERL_FBM_TABLE_OFFSET + PERL_FBM_RARE_OFFSET_FROM_TABLE); \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare);            \
         }))
 #  define BmUSEFUL(sv)                                                 \
        (*({ SV *const uggh = (SV *) (sv);                              \
@@ -1416,39 +1452,20 @@ the scalar's value cannot change unless written to.
            &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32);                  \
         }))
 #  define BmPREVIOUS(sv)                                               \
-       ({ SV *const uggh = (SV *) (sv);                                \
-          assert(SvTYPE(uggh) == SVt_PVGV);                            \
-          assert(SvVALID(uggh));                                       \
-          assert(SvPOKp(uggh));                                        \
-          assert(SvCUR(uggh) + PERL_FBM_TABLE_OFFSET <= SvLEN(uggh));  \
-          (*(U8*)(SvEND(uggh) + PERL_FBM_TABLE_OFFSET                  \
-                 + PERL_FBM_PREVIOUS_H_OFFSET_FROM_TABLE) << 8)        \
-              | (*(U8*)(SvEND(uggh) + PERL_FBM_TABLE_OFFSET            \
-                       + PERL_FBM_PREVIOUS_L_OFFSET_FROM_TABLE));      \
-       })
+       (*({ SV *const uggh = (SV *) (sv);                              \
+               assert(SvTYPE(uggh) == SVt_PVGV);                       \
+               assert(SvVALID(uggh));                                  \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous);        \
+        }))
 #else
-#  define BmRARE(sv)                                                   \
-    (*(U8*)(SvEND(sv)                                                  \
-           + PERL_FBM_TABLE_OFFSET + PERL_FBM_RARE_OFFSET_FROM_TABLE))
-
-#  define BmUSEFUL(sv) ((XPVGV*)  SvANY(sv))->xiv_u.xivu_i32
-#  define BmPREVIOUS(sv)                                               \
-    ((*(U8*)(SvEND(sv) + PERL_FBM_TABLE_OFFSET                         \
-          + PERL_FBM_PREVIOUS_H_OFFSET_FROM_TABLE) << 8)               \
-       | (*(U8*)(SvEND(sv) + PERL_FBM_TABLE_OFFSET                     \
-          + PERL_FBM_PREVIOUS_L_OFFSET_FROM_TABLE)))                   \
+#  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 { assert(SvTYPE(sv) == SVt_PVGV);                       \
-       assert(SvVALID(sv));                                            \
-       assert(SvPOKp(sv));                                             \
-       assert(SvCUR(sv) + PERL_FBM_TABLE_OFFSET <= SvLEN(sv));         \
-       *(U8*)(SvEND(sv) + PERL_FBM_TABLE_OFFSET                        \
-              + PERL_FBM_PREVIOUS_H_OFFSET_FROM_TABLE) = (U8)((U32)(val)>>8); \
-       *(U8*)(SvEND(sv) + PERL_FBM_TABLE_OFFSET                        \
-              + PERL_FBM_PREVIOUS_L_OFFSET_FROM_TABLE) = (U8)(val);    \
-    } STMT_END
+    STMT_START { BmPREVIOUS(sv) = val; } STMT_END
 
 #define FmLINES(sv)    ((XPVFM*)  SvANY(sv))->xfm_lines
 
diff --git a/util.c b/util.c
index fb77773..1c64b94 100644 (file)
--- a/util.c
+++ b/util.c
@@ -492,6 +492,8 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
        return;
     SvUPGRADE(sv, SVt_PVGV);
     SvIOK_off(sv);
+    SvNOK_off(sv);
+    SvVALID_on(sv);
     if (len > 2) {
        const unsigned char *sb;
        const U8 mlen = (len>255) ? 255 : (U8)len;
@@ -502,7 +504,7 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
            = (unsigned char*)(SvPVX_mutable(sv) + len + PERL_FBM_TABLE_OFFSET);
        s = table - 1 - PERL_FBM_TABLE_OFFSET;  /* last char */
        memset((void*)table, mlen, 256);
-       table[PERL_FBM_FLAGS_OFFSET_FROM_TABLE] = (U8)flags;
+       BmFLAGS(sv) = (U8)flags;
        i = 0;
        sb = s - mlen + 1;                      /* first char (maybe) */
        while (s >= sb) {
@@ -514,7 +516,6 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
        Sv_Grow(sv, len + PERL_FBM_TABLE_OFFSET);
     }
     sv_magic(sv, NULL, PERL_MAGIC_bm, NULL, 0);        /* deep magic */
-    SvVALID_on(sv);
 
     s = (const unsigned char*)(SvPVX_const(sv));       /* deeper magic */
     for (i = 0; i < len; i++) {
@@ -528,8 +529,8 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
     BmUSEFUL(sv) = 100;                        /* Initial value */
     if (flags & FBMcf_TAIL)
        SvTAIL_on(sv);
-    DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %d\n",
-                         BmRARE(sv),BmPREVIOUS(sv)));
+    DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %lu\n",
+                         BmRARE(sv),(unsigned long)BmPREVIOUS(sv)));
 }
 
 /* If SvTAIL(littlestr), it has a fake '\n' at end. */
@@ -724,7 +725,7 @@ Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *lit
        }
       check_end:
        if ( s == bigend
-            && (table[PERL_FBM_FLAGS_OFFSET_FROM_TABLE] & FBMcf_TAIL)
+            && (BmFLAGS(littlestr) & FBMcf_TAIL)
             && memEQ((char *)(bigend - littlelen),
                      (char *)(oldlittle - littlelen), littlelen) )
            return (char*)bigend - littlelen;