]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
Split CHECK_LEFTFIX into CHECK_{INFIX,PREFIX}
authorJustin Viiret <justin.viiret@intel.com>
Thu, 11 Feb 2016 04:21:18 +0000 (15:21 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 1 Mar 2016 00:35:08 +0000 (11:35 +1100)
src/rose/program_runtime.h
src/rose/rose_build_bytecode.cpp
src/rose/rose_dump.cpp
src/rose/rose_program.h

index bdada9e149cb7ca8d407d20bbf7fc270a531564b..590d9ec3143a96c3b30fcab3755d0d0d28041aa5 100644 (file)
@@ -144,8 +144,9 @@ void rosePushDelayedMatch(const struct RoseEngine *t,
 static rose_inline
 char roseLeftfixCheckMiracles(const struct RoseEngine *t,
                               const struct LeftNfaInfo *left,
-                              struct core_info *ci, struct mq *q, u64a end) {
-    if (left->transient) {
+                              struct core_info *ci, struct mq *q, u64a end,
+                              const char is_infix) {
+    if (!is_infix && left->transient) {
         // Miracles won't help us with transient leftfix engines; they only
         // scan for a limited time anyway.
         return 1;
@@ -178,7 +179,7 @@ found_miracle:
 
     // If we're a prefix, then a miracle effectively results in us needing to
     // re-init our state and start fresh.
-    if (!left->infix) {
+    if (!is_infix) {
         if (miracle_loc != begin_loc) {
             DEBUG_PRINTF("re-init prefix state\n");
             q->cur = q->end = 0;
@@ -355,9 +356,10 @@ hwlmcb_rv_t roseTriggerSuffix(const struct RoseEngine *t,
     return HWLM_CONTINUE_MATCHING;
 }
 
-static rose_inline
+static really_inline
 char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
-                     u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end) {
+                     u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end,
+                     const char is_infix) {
     struct core_info *ci = &scratch->core_info;
 
     u32 ri = queueToLeftIndex(t, qi);
@@ -365,10 +367,12 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
 
     DEBUG_PRINTF("testing %s %s %u/%u with lag %u (maxLag=%u)\n",
                  (left->transient ? "transient" : "active"),
-                 (left->infix ? "infix" : "prefix"),
+                 (is_infix ? "infix" : "prefix"),
                  ri, qi, leftfixLag, left->maxLag);
 
     assert(leftfixLag <= left->maxLag);
+    assert(left->infix == is_infix);
+    assert(!is_infix || !left->transient); // Only prefixes can be transient.
 
     struct mq *q = scratch->queues + qi;
     char *state = scratch->core_info.state;
@@ -398,7 +402,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
         initRoseQueue(t, qi, left, scratch);
         if (ci->buf_offset) { // there have been writes before us!
             s32 sp;
-            if (left->transient) {
+            if (!is_infix && left->transient) {
                 sp = -(s32)ci->hlen;
             } else {
                 sp = -(s32)loadRoseDelay(t, state, left);
@@ -408,7 +412,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
              * at stream boundary */
 
             pushQueueAt(q, 0, MQE_START, sp);
-            if (left->infix || (ci->buf_offset + sp > 0 && !left->transient)) {
+            if (is_infix || (ci->buf_offset + sp > 0 && !left->transient)) {
                 loadStreamState(q->nfa, q, sp);
             } else {
                 pushQueueAt(q, 1, MQE_TOP, sp);
@@ -425,7 +429,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
     assert(loc >= q_cur_loc(q));
     assert(leftfixReport != MO_INVALID_IDX);
 
-    if (left->transient) {
+    if (!is_infix && left->transient) {
         s64a start_loc = loc - left->transient;
         if (q_cur_loc(q) < start_loc) {
             q->cur = q->end = 0;
@@ -436,7 +440,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
     }
 
     if (q_cur_loc(q) < loc || q_last_type(q) != MQE_START) {
-        if (left->infix) {
+        if (is_infix) {
             if (infixTooOld(q, loc)) {
                 DEBUG_PRINTF("infix %u died of old age\n", ri);
                 goto nfa_dead;
@@ -445,7 +449,7 @@ char roseTestLeftfix(const struct RoseEngine *t, struct hs_scratch *scratch,
             reduceInfixQueue(q, loc, left->maxQueueLen, q->nfa->maxWidth);
         }
 
-        if (!roseLeftfixCheckMiracles(t, left, ci, q, end)) {
+        if (!roseLeftfixCheckMiracles(t, left, ci, q, end, is_infix)) {
             DEBUG_PRINTF("leftfix %u died due to miracle\n", ri);
             goto nfa_dead;
         }
@@ -482,6 +486,18 @@ nfa_dead:
     return 0;
 }
 
+static rose_inline
+char roseTestPrefix(const struct RoseEngine *t, struct hs_scratch *scratch,
+                    u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end) {
+    return roseTestLeftfix(t, scratch, qi, leftfixLag, leftfixReport, end, 0);
+}
+
+static rose_inline
+char roseTestInfix(const struct RoseEngine *t, struct hs_scratch *scratch,
+                   u32 qi, u32 leftfixLag, ReportID leftfixReport, u64a end) {
+    return roseTestLeftfix(t, scratch, qi, leftfixLag, leftfixReport, end, 1);
+}
+
 static rose_inline
 void roseTriggerInfix(const struct RoseEngine *t, struct hs_scratch *scratch,
                       u64a start, u64a end, u32 qi, u32 topEvent, u8 cancel) {
@@ -921,10 +937,21 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
             }
             PROGRAM_NEXT_INSTRUCTION
 
-            PROGRAM_CASE(CHECK_LEFTFIX) {
-                if (!roseTestLeftfix(t, scratch, ri->queue, ri->lag, ri->report,
-                                     end)) {
-                    DEBUG_PRINTF("failed leftfix check\n");
+            PROGRAM_CASE(CHECK_INFIX) {
+                if (!roseTestInfix(t, scratch, ri->queue, ri->lag, ri->report,
+                                   end)) {
+                    DEBUG_PRINTF("failed infix check\n");
+                    assert(ri->fail_jump); // must progress
+                    pc += ri->fail_jump;
+                    continue;
+                }
+            }
+            PROGRAM_NEXT_INSTRUCTION
+
+            PROGRAM_CASE(CHECK_PREFIX) {
+                if (!roseTestPrefix(t, scratch, ri->queue, ri->lag, ri->report,
+                                    end)) {
+                    DEBUG_PRINTF("failed prefix check\n");
                     assert(ri->fail_jump); // must progress
                     pc += ri->fail_jump;
                     continue;
index 5354955a54ec04d23459f2f5f1ea523eae5f9d67..4518b43406bd994739755975e35f5d7ef5f50fbc 100644 (file)
@@ -194,7 +194,8 @@ public:
         case ROSE_INSTR_CHECK_BOUNDS: return &u.checkBounds;
         case ROSE_INSTR_CHECK_NOT_HANDLED: return &u.checkNotHandled;
         case ROSE_INSTR_CHECK_LOOKAROUND: return &u.checkLookaround;
-        case ROSE_INSTR_CHECK_LEFTFIX: return &u.checkLeftfix;
+        case ROSE_INSTR_CHECK_INFIX: return &u.checkInfix;
+        case ROSE_INSTR_CHECK_PREFIX: return &u.checkPrefix;
         case ROSE_INSTR_ANCHORED_DELAY: return &u.anchoredDelay;
         case ROSE_INSTR_PUSH_DELAYED: return &u.pushDelayed;
         case ROSE_INSTR_CATCH_UP: return &u.catchUp;
@@ -236,7 +237,8 @@ public:
         case ROSE_INSTR_CHECK_BOUNDS: return sizeof(u.checkBounds);
         case ROSE_INSTR_CHECK_NOT_HANDLED: return sizeof(u.checkNotHandled);
         case ROSE_INSTR_CHECK_LOOKAROUND: return sizeof(u.checkLookaround);
-        case ROSE_INSTR_CHECK_LEFTFIX: return sizeof(u.checkLeftfix);
+        case ROSE_INSTR_CHECK_INFIX: return sizeof(u.checkInfix);
+        case ROSE_INSTR_CHECK_PREFIX: return sizeof(u.checkPrefix);
         case ROSE_INSTR_ANCHORED_DELAY: return sizeof(u.anchoredDelay);
         case ROSE_INSTR_PUSH_DELAYED: return sizeof(u.pushDelayed);
         case ROSE_INSTR_CATCH_UP: return sizeof(u.catchUp);
@@ -277,7 +279,8 @@ public:
         ROSE_STRUCT_CHECK_BOUNDS checkBounds;
         ROSE_STRUCT_CHECK_NOT_HANDLED checkNotHandled;
         ROSE_STRUCT_CHECK_LOOKAROUND checkLookaround;
-        ROSE_STRUCT_CHECK_LEFTFIX checkLeftfix;
+        ROSE_STRUCT_CHECK_INFIX checkInfix;
+        ROSE_STRUCT_CHECK_PREFIX checkPrefix;
         ROSE_STRUCT_ANCHORED_DELAY anchoredDelay;
         ROSE_STRUCT_PUSH_DELAYED pushDelayed;
         ROSE_STRUCT_CATCH_UP catchUp;
@@ -2724,8 +2727,11 @@ flattenProgram(const vector<vector<RoseInstruction>> &programs) {
         case ROSE_INSTR_CHECK_LOOKAROUND:
             ri.u.checkLookaround.fail_jump = jump_val;
             break;
-        case ROSE_INSTR_CHECK_LEFTFIX:
-            ri.u.checkLeftfix.fail_jump = jump_val;
+        case ROSE_INSTR_CHECK_INFIX:
+            ri.u.checkInfix.fail_jump = jump_val;
+            break;
+        case ROSE_INSTR_CHECK_PREFIX:
+            ri.u.checkPrefix.fail_jump = jump_val;
             break;
         case ROSE_INSTR_DEDUPE:
             ri.u.dedupe.fail_jump = jump_val;
@@ -2986,11 +2992,22 @@ void makeRoleCheckLeftfix(RoseBuildImpl &build, build_context &bc, RoseVertex v,
     assert(!build.cc.streaming ||
            build.g[v].left.lag <= MAX_STORED_LEFTFIX_LAG);
 
-    auto ri = RoseInstruction(ROSE_INSTR_CHECK_LEFTFIX, JumpTarget::NEXT_BLOCK);
-    ri.u.checkLeftfix.queue = lni.queue;
-    ri.u.checkLeftfix.lag = build.g[v].left.lag;
-    ri.u.checkLeftfix.report = build.g[v].left.leftfix_report;
-    program.push_back(ri);
+    bool is_prefix = build.isRootSuccessor(v);
+    if (is_prefix) {
+        auto ri =
+            RoseInstruction(ROSE_INSTR_CHECK_PREFIX, JumpTarget::NEXT_BLOCK);
+        ri.u.checkPrefix.queue = lni.queue;
+        ri.u.checkPrefix.lag = build.g[v].left.lag;
+        ri.u.checkPrefix.report = build.g[v].left.leftfix_report;
+        program.push_back(move(ri));
+    } else {
+        auto ri =
+            RoseInstruction(ROSE_INSTR_CHECK_INFIX, JumpTarget::NEXT_BLOCK);
+        ri.u.checkInfix.queue = lni.queue;
+        ri.u.checkInfix.lag = build.g[v].left.lag;
+        ri.u.checkInfix.report = build.g[v].left.leftfix_report;
+        program.push_back(move(ri));
+    }
 }
 
 static
index 25c6e77dac1468245345a8fbd50d5540b077edd6..a188c78b77bfbd6873ee7ffae443096616dadbb8 100644 (file)
@@ -288,7 +288,15 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
             }
             PROGRAM_NEXT_INSTRUCTION
 
-            PROGRAM_CASE(CHECK_LEFTFIX) {
+            PROGRAM_CASE(CHECK_INFIX) {
+                os << "    queue " << ri->queue << endl;
+                os << "    lag " << ri->lag << endl;
+                os << "    report " << ri->report << endl;
+                os << "    fail_jump +" << ri->fail_jump << endl;
+            }
+            PROGRAM_NEXT_INSTRUCTION
+
+            PROGRAM_CASE(CHECK_PREFIX) {
                 os << "    queue " << ri->queue << endl;
                 os << "    lag " << ri->lag << endl;
                 os << "    report " << ri->report << endl;
index 81852f097ba989110891286792048a50e6c0691f..36a9aabdab025b8544d82a029e6636b0eec7cefc 100644 (file)
@@ -49,7 +49,8 @@ enum RoseInstructionCode {
     ROSE_INSTR_CHECK_BOUNDS,      //!< Bounds on distance from offset 0.
     ROSE_INSTR_CHECK_NOT_HANDLED, //!< Test & set role in "handled".
     ROSE_INSTR_CHECK_LOOKAROUND,  //!< Lookaround check.
-    ROSE_INSTR_CHECK_LEFTFIX,     //!< Leftfix must be in accept state.
+    ROSE_INSTR_CHECK_INFIX,       //!< Infix engine must be in accept state.
+    ROSE_INSTR_CHECK_PREFIX,      //!< Prefix engine must be in accept state.
     ROSE_INSTR_PUSH_DELAYED,      //!< Push delayed literal matches.
     ROSE_INSTR_CATCH_UP,          //!< Catch up engines, anchored matches.
     ROSE_INSTR_SOM_ADJUST,        //!< Set SOM from a distance to EOM.
@@ -141,7 +142,15 @@ struct ROSE_STRUCT_CHECK_LOOKAROUND {
     u32 fail_jump; //!< Jump forward this many bytes on failure.
 };
 
-struct ROSE_STRUCT_CHECK_LEFTFIX {
+struct ROSE_STRUCT_CHECK_INFIX {
+    u8 code; //!< From enum RoseInstructionCode.
+    u32 queue; //!< Queue of leftfix to check.
+    u32 lag; //!< Lag of leftfix for this case.
+    ReportID report; //!< ReportID of leftfix to check.
+    u32 fail_jump; //!< Jump forward this many bytes on failure.
+};
+
+struct ROSE_STRUCT_CHECK_PREFIX {
     u8 code; //!< From enum RoseInstructionCode.
     u32 queue; //!< Queue of leftfix to check.
     u32 lag; //!< Lag of leftfix for this case.