]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
eod: more suffix iteration into program
authorJustin Viiret <justin.viiret@intel.com>
Fri, 10 Jun 2016 04:51:15 +0000 (14:51 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Fri, 8 Jul 2016 00:54:07 +0000 (10:54 +1000)
src/rose/eod.c
src/rose/program_runtime.h
src/rose/rose_build_bytecode.cpp
src/rose/rose_dump.cpp
src/rose/rose_program.h

index 30b8db0ea6b07288ec8bf956fbc9b77e55926c00..48b330d459de3cd32561f26aa9822337f9c16a45 100644 (file)
@@ -129,47 +129,6 @@ void cleanupAfterEodMatcher(const struct RoseEngine *t, u64a offset,
     roseFlushLastByteHistory(t, scratch, offset);
 }
 
-static rose_inline
-void roseCheckEodSuffixes(const struct RoseEngine *t, u64a offset,
-                          struct hs_scratch *scratch) {
-    const u8 *aa = getActiveLeafArray(t, scratch->core_info.state);
-    const u32 aaCount = t->activeArrayCount;
-    UNUSED u32 qCount = t->queueCount;
-
-    for (u32 qi = mmbit_iterate(aa, aaCount, MMB_INVALID); qi != MMB_INVALID;
-         qi = mmbit_iterate(aa, aaCount, qi)) {
-        const struct NfaInfo *info = getNfaInfoByQueue(t, qi);
-        const struct NFA *nfa = getNfaByInfo(t, info);
-
-        assert(nfaAcceptsEod(nfa));
-
-        DEBUG_PRINTF("checking nfa %u\n", qi);
-
-        assert(fatbit_isset(scratch->aqa, qCount, qi)); /* we have just been
-                                                           triggered */
-
-        char *fstate = scratch->fullState + info->fullStateOffset;
-        const char *sstate = scratch->core_info.state + info->stateOffset;
-
-        struct mq *q = scratch->queues + qi;
-
-        pushQueueNoMerge(q, MQE_END, scratch->core_info.len);
-
-        q->context = NULL;
-        /* rose exec is used as we don't want to / can't raise matches in the
-         * history buffer. */
-        char rv = nfaQueueExecRose(q->nfa, q, MO_INVALID_IDX);
-        if (rv) { /* nfa is still alive */
-            if (nfaCheckFinalState(nfa, fstate, sstate, offset,
-                                   roseReportAdaptor, roseReportSomAdaptor,
-                                   scratch) == MO_HALT_MATCHING) {
-                DEBUG_PRINTF("user instructed us to stop\n");
-                return;
-            }
-        }
-    }
-}
-
 static rose_inline
 int roseRunEodProgram(const struct RoseEngine *t, u64a offset,
                       struct hs_scratch *scratch) {
@@ -229,8 +188,6 @@ void roseEodExec_i(const struct RoseEngine *t, u64a offset,
         if (roseEodRunIterator(t, offset, scratch) == MO_HALT_MATCHING) {
             return;
         }
-
-        roseCheckEodSuffixes(t, offset, scratch);
     }
 }
 
index a656c7151acb9ba2b48f49c435ba877a9124f010..5387f59f85d602b46354414964a9aef74066b9cd 100644 (file)
@@ -851,6 +851,48 @@ hwlmcb_rv_t roseEnginesEod(const struct RoseEngine *rose,
     return HWLM_CONTINUE_MATCHING;
 }
 
+static rose_inline
+hwlmcb_rv_t roseSuffixesEod(const struct RoseEngine *rose,
+                            struct hs_scratch *scratch, u64a offset) {
+    const u8 *aa = getActiveLeafArray(rose, scratch->core_info.state);
+    const u32 aaCount = rose->activeArrayCount;
+
+    for (u32 qi = mmbit_iterate(aa, aaCount, MMB_INVALID); qi != MMB_INVALID;
+         qi = mmbit_iterate(aa, aaCount, qi)) {
+        const struct NfaInfo *info = getNfaInfoByQueue(rose, qi);
+        const struct NFA *nfa = getNfaByInfo(rose, info);
+
+        assert(nfaAcceptsEod(nfa));
+
+        DEBUG_PRINTF("checking nfa %u\n", qi);
+
+        /* We have just been triggered. */
+        assert(fatbit_isset(scratch->aqa, rose->queueCount, qi));
+
+        char *fstate = scratch->fullState + info->fullStateOffset;
+        const char *sstate = scratch->core_info.state + info->stateOffset;
+
+        struct mq *q = scratch->queues + qi;
+
+        pushQueueNoMerge(q, MQE_END, scratch->core_info.len);
+
+        q->context = NULL;
+        /* rose exec is used as we don't want to / can't raise matches in the
+         * history buffer. */
+        if (!nfaQueueExecRose(q->nfa, q, MO_INVALID_IDX)) {
+            DEBUG_PRINTF("nfa is dead\n");
+            continue;
+        }
+        if (nfaCheckFinalState(nfa, fstate, sstate, offset, roseReportAdaptor,
+                               roseReportSomAdaptor,
+                               scratch) == MO_HALT_MATCHING) {
+            DEBUG_PRINTF("user instructed us to stop\n");
+            return HWLM_TERMINATE_MATCHING;
+        }
+    }
+    return HWLM_CONTINUE_MATCHING;
+}
+
 static
 void updateSeqPoint(struct RoseContext *tctxt, u64a offset,
                     const char from_mpv) {
@@ -1360,6 +1402,14 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
             }
             PROGRAM_NEXT_INSTRUCTION
 
+            PROGRAM_CASE(SUFFIXES_EOD) {
+                if (roseSuffixesEod(t, scratch, end) ==
+                    HWLM_TERMINATE_MATCHING) {
+                    return HWLM_TERMINATE_MATCHING;
+                }
+            }
+            PROGRAM_NEXT_INSTRUCTION
+
             PROGRAM_CASE(END) {
                 DEBUG_PRINTF("finished\n");
                 return HWLM_CONTINUE_MATCHING;
index 5d235fca121fdf733a543b48b31b94595aa2eaf0..846e3e1bab36f2bd5dfefebdc9b5ba477a1934ce 100644 (file)
@@ -224,6 +224,7 @@ public:
         case ROSE_INSTR_SPARSE_ITER_BEGIN: return &u.sparseIterBegin;
         case ROSE_INSTR_SPARSE_ITER_NEXT: return &u.sparseIterNext;
         case ROSE_INSTR_ENGINES_EOD: return &u.enginesEod;
+        case ROSE_INSTR_SUFFIXES_EOD: return &u.suffixesEod;
         case ROSE_INSTR_END: return &u.end;
         }
         assert(0);
@@ -271,6 +272,7 @@ public:
         case ROSE_INSTR_SPARSE_ITER_BEGIN: return sizeof(u.sparseIterBegin);
         case ROSE_INSTR_SPARSE_ITER_NEXT: return sizeof(u.sparseIterNext);
         case ROSE_INSTR_ENGINES_EOD: return sizeof(u.enginesEod);
+        case ROSE_INSTR_SUFFIXES_EOD: return sizeof(u.suffixesEod);
         case ROSE_INSTR_END: return sizeof(u.end);
         }
         assert(0);
@@ -317,6 +319,7 @@ public:
         ROSE_STRUCT_SPARSE_ITER_BEGIN sparseIterBegin;
         ROSE_STRUCT_SPARSE_ITER_NEXT sparseIterNext;
         ROSE_STRUCT_ENGINES_EOD enginesEod;
+        ROSE_STRUCT_SUFFIXES_EOD suffixesEod;
         ROSE_STRUCT_END end;
     } u;
 
@@ -3985,6 +3988,19 @@ vector<RoseInstruction> makeEodAnchorProgram(RoseBuildImpl &build,
     return program;
 }
 
+static
+bool hasEodAnchoredSuffix(const RoseBuildImpl &build) {
+    const RoseGraph &g = build.g;
+    for (auto v : vertices_range(g)) {
+        if (g[v].suffix && build.isInETable(v)) {
+            DEBUG_PRINTF("vertex %zu is in eod table and has a suffix\n",
+                         g[v].idx);
+            return true;
+        }
+    }
+    return false;
+}
+
 /**
  * Returns the pair (program offset, sparse iter offset).
  */
@@ -4028,13 +4044,24 @@ u32 writeEodAnchorProgram(RoseBuildImpl &build, build_context &bc) {
         }
     }
 
-    if (predProgramLists.empty()) {
-        DEBUG_PRINTF("no eod anchored roles\n");
+    vector<RoseInstruction> program;
+    if (!predProgramLists.empty()) {
+        addPredBlocks(bc, predProgramLists, program, false);
+    }
+
+    if (hasEodAnchoredSuffix(build)) {
+        if (!program.empty()) {
+            assert(program.back().code() == ROSE_INSTR_END);
+            program.pop_back();
+        }
+        program.emplace_back(ROSE_INSTR_SUFFIXES_EOD);
+    }
+
+    if (program.empty()) {
         return 0;
     }
 
-    vector<RoseInstruction> program;
-    addPredBlocks(bc, predProgramLists, program, false);
+    program = flattenProgram({program});
 
     assert(program.size() > 1);
     applyFinalSpecialisation(program);
index 8de33a4498258f5b7a332a7ae0279a858621418a..be43e559b7ead61facdafd4c951da777d9b01bcd 100644 (file)
@@ -481,6 +481,9 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
             }
             PROGRAM_NEXT_INSTRUCTION
 
+            PROGRAM_CASE(SUFFIXES_EOD) {}
+            PROGRAM_NEXT_INSTRUCTION
+
             PROGRAM_CASE(END) { return; }
             PROGRAM_NEXT_INSTRUCTION
 
index b89611171891d35c3715bc92da52b3cf784cedf6..4a5521ef9f9388b10a14c3adeb790321a9014466 100644 (file)
@@ -100,6 +100,10 @@ enum RoseInstructionCode {
     /** \brief Check outfixes and suffixes for EOD and fire reports if so. */
     ROSE_INSTR_ENGINES_EOD,
 
+    /** \brief Catch up and check active suffixes for EOD and fire reports if
+     * so. */
+    ROSE_INSTR_SUFFIXES_EOD,
+
     ROSE_INSTR_END                //!< End of program.
 };
 
@@ -361,6 +365,10 @@ struct ROSE_STRUCT_ENGINES_EOD {
     u32 iter_offset; //!< Offset of mmbit_sparse_iter structure.
 };
 
+struct ROSE_STRUCT_SUFFIXES_EOD {
+    u8 code; //!< From enum RoseInstructionCode.
+};
+
 struct ROSE_STRUCT_END {
     u8 code; //!< From enum RoseInstructionCode.
 };