Change 4 byte bitmap to 32 bit single word
authorKarl Williamson <public@khwilliamson.com>
Fri, 7 Dec 2012 05:15:52 +0000 (22:15 -0700)
committerKarl Williamson <public@khwilliamson.com>
Sun, 9 Dec 2012 19:08:29 +0000 (12:08 -0700)
I presume that the reason this bitmap was expressed in bytes was that
the macros for dealing with that were already readily available and
familiar, and because it could easily be grown.

However, it's extremely unlikely that we would ever need more bits.
This bit map is for the Posix character classes, and no one is making
more of them.  There is currently one spare bit available, and if we
don't back out of the \s and [:space:] unification, a second will become
available in 5.20 or 5.22.

Using a single word is more efficient, so this changes to use that.
Should we ever need more bits, we can change back.

regcomp.c
regcomp.h

index 87ded26..2080138 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -992,11 +992,7 @@ S_cl_or(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl, con
            /* OR char bitmap and class bitmap separately */
            for (i = 0; i < ANYOF_BITMAP_SIZE; i++)
                cl->bitmap[i] |= or_with->bitmap[i];
-           if (ANYOF_CLASS_TEST_ANY_SET(or_with)) {
-               for (i = 0; i < ANYOF_CLASSBITMAP_SIZE; i++)
-                   cl->classflags[i] |= or_with->classflags[i];
-               cl->flags |= ANYOF_CLASS;
-           }
+            ANYOF_CLASS_OR(or_with, cl);
        }
        else { /* XXXX: logic is complicated, leave it along for a moment. */
            cl_anything(pRExC_state, cl);
index 74ca44a..4e05a9f 100644 (file)
--- a/regcomp.h
+++ b/regcomp.h
@@ -178,7 +178,6 @@ struct regnode_2 {
 
 
 #define ANYOF_BITMAP_SIZE      32      /* 256 b/(8 b/B) */
-#define ANYOF_CLASSBITMAP_SIZE  4      /* up to 32 (8*4) named classes */
 
 /* also used by trie */
 struct regnode_charclass {
@@ -196,7 +195,7 @@ struct regnode_charclass_class {
     U16 next_off;
     U32 arg1;                                  /* used as ptr in S_regclass */
     char bitmap[ANYOF_BITMAP_SIZE];            /* both compile-time */
-    char classflags[ANYOF_CLASSBITMAP_SIZE];   /* and run-time */
+    U32 classflags;                            /* and run-time */
 };
 
 /* XXX fix this description.
@@ -459,16 +458,18 @@ struct regnode_charclass_class {
 
 #define ANYOF_BIT(c)           (1 << ((c) & 7))
 
-#define ANYOF_CLASS_BYTE(p, c) (((struct regnode_charclass_class*)(p))->classflags[((c) >> 3) & 3])
-#define ANYOF_CLASS_SET(p, c)  (ANYOF_CLASS_BYTE(p, c) |=  ANYOF_BIT(c))
-#define ANYOF_CLASS_CLEAR(p, c)        (ANYOF_CLASS_BYTE(p, c) &= ~ANYOF_BIT(c))
-#define ANYOF_CLASS_TEST(p, c) (ANYOF_CLASS_BYTE(p, c) &   ANYOF_BIT(c))
+#define ANYOF_CLASS_SET(p, c)  (((struct regnode_charclass_class*) (p))->classflags |= (1U << (c)))
+#define ANYOF_CLASS_CLEAR(p, c)        (((struct regnode_charclass_class*) (p))->classflags &= ~ (1U <<(c)))
+#define ANYOF_CLASS_TEST(p, c) (((struct regnode_charclass_class*) (p))->classflags & (1U << (c)))
 
-#define ANYOF_CLASS_ZERO(ret)  Zero(((struct regnode_charclass_class*)(ret))->classflags, ANYOF_CLASSBITMAP_SIZE, char)
-#define ANYOF_CLASS_SETALL(ret)                \
-       memset (((struct regnode_charclass_class*)(ret))->classflags, 255, ANYOF_CLASSBITMAP_SIZE)
-#define ANYOF_BITMAP_ZERO(ret) Zero(((struct regnode_charclass*)(ret))->bitmap, ANYOF_BITMAP_SIZE, char)
+#define ANYOF_CLASS_ZERO(ret)  STMT_START { ((struct regnode_charclass_class*) (ret))->classflags = 0; } STMT_END
+
+/* Shifts a bit to get, eg. 0x4000_0000, then subtracts 1 to get 0x3FFF_FFFF */
+#define ANYOF_CLASS_SETALL(ret) STMT_START { ((struct regnode_charclass_class*) (ret))->classflags = ((1U << ((ANYOF_MAX) - 1))) - 1; } STMT_END
+
+#define ANYOF_CLASS_OR(source, dest) STMT_START { (dest)->classflags |= source->classflags ; } STMT_END
 
+#define ANYOF_BITMAP_ZERO(ret) Zero(((struct regnode_charclass*)(ret))->bitmap, ANYOF_BITMAP_SIZE, char)
 #define ANYOF_BITMAP(p)                (((struct regnode_charclass*)(p))->bitmap)
 #define ANYOF_BITMAP_BYTE(p, c)        (ANYOF_BITMAP(p)[(((U8)(c)) >> 3) & 31])
 #define ANYOF_BITMAP_SET(p, c) (ANYOF_BITMAP_BYTE(p, c) |=  ANYOF_BIT(c))
@@ -486,12 +487,9 @@ struct regnode_charclass_class {
 #define ANYOF_SKIP             ((ANYOF_SIZE - 1)/sizeof(regnode))
 #define ANYOF_CLASS_SKIP       ((ANYOF_CLASS_SIZE - 1)/sizeof(regnode))
 
-#if ANYOF_CLASSBITMAP_SIZE != 4
-#   error ANYOF_CLASSBITMAP_SIZE is expected to be 4
-#endif
-#define ANYOF_CLASS_TEST_ANY_SET(p) ((ANYOF_FLAGS(p) & ANYOF_CLASS)         \
-       && memNE (((struct regnode_charclass_class*)(p))->classflags,       \
-                   "\0\0\0\0", ANYOF_CLASSBITMAP_SIZE))
+#define ANYOF_CLASS_TEST_ANY_SET(p)                               \
+        ((ANYOF_FLAGS(p) & (ANYOF_CLASS|ANYOF_IS_SYNTHETIC))         \
+        && (((struct regnode_charclass_class*)(p))->classflags))
 /*#define ANYOF_CLASS_ADD_SKIP (ANYOF_CLASS_SKIP - ANYOF_SKIP)
  * */