mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-11-18 18:20:35 +03:00
Logical combination: support EOD match from purely negative case.
This commit is contained in:
@@ -591,6 +591,23 @@ int roseRunFlushCombProgram(const struct RoseEngine *rose,
|
||||
return MO_CONTINUE_MATCHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Execute last flush combination program.
|
||||
*
|
||||
* Returns MO_HALT_MATCHING if the stream is exhausted or the user has
|
||||
* instructed us to halt, or MO_CONTINUE_MATCHING otherwise.
|
||||
*/
|
||||
int roseRunLastFlushCombProgram(const struct RoseEngine *rose,
|
||||
struct hs_scratch *scratch, u64a end) {
|
||||
hwlmcb_rv_t rv = roseRunProgram(rose, scratch,
|
||||
rose->lastFlushCombProgramOffset,
|
||||
0, end, 0);
|
||||
if (rv == HWLM_TERMINATE_MATCHING) {
|
||||
return MO_HALT_MATCHING;
|
||||
}
|
||||
return MO_CONTINUE_MATCHING;
|
||||
}
|
||||
|
||||
int roseReportAdaptor(u64a start, u64a end, ReportID id, void *context) {
|
||||
struct hs_scratch *scratch = context;
|
||||
assert(scratch && scratch->magic == SCRATCH_MAGIC);
|
||||
|
||||
@@ -1875,6 +1875,49 @@ hwlmcb_rv_t flushActiveCombinations(const struct RoseEngine *t,
|
||||
return HWLM_CONTINUE_MATCHING;
|
||||
}
|
||||
|
||||
static rose_inline
|
||||
hwlmcb_rv_t checkPurelyNegatives(const struct RoseEngine *t,
|
||||
struct hs_scratch *scratch, u64a end) {
|
||||
for (u32 i = 0; i < t->ckeyCount; i++) {
|
||||
const struct CombInfo *combInfoMap = (const struct CombInfo *)
|
||||
((const char *)t + t->combInfoMapOffset);
|
||||
const struct CombInfo *ci = combInfoMap + i;
|
||||
if ((ci->min_offset != 0) && (end < ci->min_offset)) {
|
||||
DEBUG_PRINTF("halt: before min_offset=%llu\n", ci->min_offset);
|
||||
continue;
|
||||
}
|
||||
if ((ci->max_offset != MAX_OFFSET) && (end > ci->max_offset)) {
|
||||
DEBUG_PRINTF("halt: after max_offset=%llu\n", ci->max_offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("check ekey %u\n", ci->ekey);
|
||||
if (ci->ekey != INVALID_EKEY) {
|
||||
assert(ci->ekey < t->ekeyCount);
|
||||
const char *evec = scratch->core_info.exhaustionVector;
|
||||
if (isExhausted(t, evec, ci->ekey)) {
|
||||
DEBUG_PRINTF("ekey %u already set, match is exhausted\n",
|
||||
ci->ekey);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("check ckey %u purely negative\n", i);
|
||||
char *lvec = scratch->core_info.logicalVector;
|
||||
if (!isPurelyNegativeMatch(t, lvec, ci->start, ci->result)) {
|
||||
DEBUG_PRINTF("Logical Combination from purely negative Failed!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("Logical Combination from purely negative Passed!\n");
|
||||
if (roseReport(t, scratch, end, ci->id, 0,
|
||||
ci->ekey) == HWLM_TERMINATE_MATCHING) {
|
||||
return HWLM_TERMINATE_MATCHING;
|
||||
}
|
||||
}
|
||||
return HWLM_CONTINUE_MATCHING;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#define PROGRAM_CASE(name) \
|
||||
case ROSE_INSTR_##name: { \
|
||||
@@ -2004,7 +2047,8 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
|
||||
&&LABEL_ROSE_INSTR_SET_LOGICAL,
|
||||
&&LABEL_ROSE_INSTR_SET_COMBINATION,
|
||||
&&LABEL_ROSE_INSTR_FLUSH_COMBINATION,
|
||||
&&LABEL_ROSE_INSTR_SET_EXHAUST
|
||||
&&LABEL_ROSE_INSTR_SET_EXHAUST,
|
||||
&&LABEL_ROSE_INSTR_LAST_FLUSH_COMBINATION
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -2772,6 +2816,19 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(LAST_FLUSH_COMBINATION) {
|
||||
assert(end >= tctxt->lastCombMatchOffset);
|
||||
if (flushActiveCombinations(t, scratch)
|
||||
== HWLM_TERMINATE_MATCHING) {
|
||||
return HWLM_TERMINATE_MATCHING;
|
||||
}
|
||||
if (checkPurelyNegatives(t, scratch, end)
|
||||
== HWLM_TERMINATE_MATCHING) {
|
||||
return HWLM_TERMINATE_MATCHING;
|
||||
}
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
default: {
|
||||
assert(0); // unreachable
|
||||
scratch->core_info.status |= STATUS_ERROR;
|
||||
@@ -3082,6 +3139,19 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t,
|
||||
}
|
||||
L_PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
L_PROGRAM_CASE(LAST_FLUSH_COMBINATION) {
|
||||
assert(end >= tctxt->lastCombMatchOffset);
|
||||
if (flushActiveCombinations(t, scratch)
|
||||
== HWLM_TERMINATE_MATCHING) {
|
||||
return HWLM_TERMINATE_MATCHING;
|
||||
}
|
||||
if (checkPurelyNegatives(t, scratch, end)
|
||||
== HWLM_TERMINATE_MATCHING) {
|
||||
return HWLM_TERMINATE_MATCHING;
|
||||
}
|
||||
}
|
||||
L_PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
default: {
|
||||
assert(0); // unreachable
|
||||
scratch->core_info.status |= STATUS_ERROR;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, Intel Corporation
|
||||
* Copyright (c) 2015-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -56,4 +56,7 @@ int roseRunBoundaryProgram(const struct RoseEngine *rose, u32 program,
|
||||
int roseRunFlushCombProgram(const struct RoseEngine *rose,
|
||||
struct hs_scratch *scratch, u64a end);
|
||||
|
||||
int roseRunLastFlushCombProgram(const struct RoseEngine *rose,
|
||||
struct hs_scratch *scratch, u64a end);
|
||||
|
||||
#endif // ROSE_H
|
||||
|
||||
@@ -3370,6 +3370,15 @@ RoseProgram makeFlushCombProgram(const RoseEngine &t) {
|
||||
return program;
|
||||
}
|
||||
|
||||
static
|
||||
RoseProgram makeLastFlushCombProgram(const RoseEngine &t) {
|
||||
RoseProgram program;
|
||||
if (t.ckeyCount) {
|
||||
addLastFlushCombinationProgram(program);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
static
|
||||
u32 history_required(const rose_literal_id &key) {
|
||||
if (key.msk.size() < key.s.length()) {
|
||||
@@ -3740,6 +3749,10 @@ bytecode_ptr<RoseEngine> RoseBuildImpl::buildFinalEngine(u32 minWidth) {
|
||||
auto flushComb_prog = makeFlushCombProgram(proto);
|
||||
proto.flushCombProgramOffset = writeProgram(bc, move(flushComb_prog));
|
||||
|
||||
auto lastFlushComb_prog = makeLastFlushCombProgram(proto);
|
||||
proto.lastFlushCombProgramOffset =
|
||||
writeProgram(bc, move(lastFlushComb_prog));
|
||||
|
||||
// Build anchored matcher.
|
||||
auto atable = buildAnchoredMatcher(*this, fragments, anchored_dfas);
|
||||
if (atable) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, Intel Corporation
|
||||
* Copyright (c) 2015-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -1486,6 +1486,9 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
|
||||
}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
PROGRAM_CASE(LAST_FLUSH_COMBINATION) {}
|
||||
PROGRAM_NEXT_INSTRUCTION
|
||||
|
||||
default:
|
||||
os << " UNKNOWN (code " << int{code} << ")" << endl;
|
||||
os << " <stopping>" << endl;
|
||||
@@ -1557,6 +1560,25 @@ void dumpRoseFlushCombPrograms(const RoseEngine *t, const string &filename) {
|
||||
os.close();
|
||||
}
|
||||
|
||||
static
|
||||
void dumpRoseLastFlushCombPrograms(const RoseEngine *t,
|
||||
const string &filename) {
|
||||
ofstream os(filename);
|
||||
const char *base = (const char *)t;
|
||||
|
||||
if (t->lastFlushCombProgramOffset) {
|
||||
os << "Last Flush Combination Program @ "
|
||||
<< t->lastFlushCombProgramOffset
|
||||
<< ":" << endl;
|
||||
dumpProgram(os, t, base + t->lastFlushCombProgramOffset);
|
||||
os << endl;
|
||||
} else {
|
||||
os << "<No Last Flush Combination Program>" << endl;
|
||||
}
|
||||
|
||||
os.close();
|
||||
}
|
||||
|
||||
static
|
||||
void dumpRoseReportPrograms(const RoseEngine *t, const string &filename) {
|
||||
ofstream os(filename);
|
||||
@@ -2249,6 +2271,8 @@ void roseDumpPrograms(const vector<LitFragment> &fragments, const RoseEngine *t,
|
||||
dumpRoseLitPrograms(fragments, t, base + "/rose_lit_programs.txt");
|
||||
dumpRoseEodPrograms(t, base + "/rose_eod_programs.txt");
|
||||
dumpRoseFlushCombPrograms(t, base + "/rose_flush_comb_programs.txt");
|
||||
dumpRoseLastFlushCombPrograms(t,
|
||||
base + "/rose_last_flush_comb_programs.txt");
|
||||
dumpRoseReportPrograms(t, base + "/rose_report_programs.txt");
|
||||
dumpRoseAnchoredPrograms(t, base + "/rose_anchored_programs.txt");
|
||||
dumpRoseDelayPrograms(t, base + "/rose_delay_programs.txt");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, Intel Corporation
|
||||
* Copyright (c) 2017-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -48,6 +48,7 @@ RoseInstrMatcherEod::~RoseInstrMatcherEod() = default;
|
||||
RoseInstrEnd::~RoseInstrEnd() = default;
|
||||
RoseInstrClearWorkDone::~RoseInstrClearWorkDone() = default;
|
||||
RoseInstrFlushCombination::~RoseInstrFlushCombination() = default;
|
||||
RoseInstrLastFlushCombination::~RoseInstrLastFlushCombination() = default;
|
||||
|
||||
using OffsetMap = RoseInstruction::OffsetMap;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, Intel Corporation
|
||||
* Copyright (c) 2017-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -2206,6 +2206,14 @@ public:
|
||||
~RoseInstrFlushCombination() override;
|
||||
};
|
||||
|
||||
class RoseInstrLastFlushCombination
|
||||
: public RoseInstrBaseTrivial<ROSE_INSTR_LAST_FLUSH_COMBINATION,
|
||||
ROSE_STRUCT_LAST_FLUSH_COMBINATION,
|
||||
RoseInstrLastFlushCombination> {
|
||||
public:
|
||||
~RoseInstrLastFlushCombination() override;
|
||||
};
|
||||
|
||||
class RoseInstrSetExhaust
|
||||
: public RoseInstrBaseNoTargets<ROSE_INSTR_SET_EXHAUST,
|
||||
ROSE_STRUCT_SET_EXHAUST,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, Intel Corporation
|
||||
* Copyright (c) 2016-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -317,6 +317,10 @@ void addFlushCombinationProgram(RoseProgram &program) {
|
||||
program.add_before_end(make_unique<RoseInstrFlushCombination>());
|
||||
}
|
||||
|
||||
void addLastFlushCombinationProgram(RoseProgram &program) {
|
||||
program.add_before_end(make_unique<RoseInstrLastFlushCombination>());
|
||||
}
|
||||
|
||||
static
|
||||
void makeRoleCheckLeftfix(const RoseBuildImpl &build,
|
||||
const map<RoseVertex, left_build_info> &leftfix_info,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, Intel Corporation
|
||||
* Copyright (c) 2016-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -188,6 +188,7 @@ void addEnginesEodProgram(u32 eodNfaIterOffset, RoseProgram &program);
|
||||
void addSuffixesEodProgram(RoseProgram &program);
|
||||
void addMatcherEodProgram(RoseProgram &program);
|
||||
void addFlushCombinationProgram(RoseProgram &program);
|
||||
void addLastFlushCombinationProgram(RoseProgram &program);
|
||||
|
||||
static constexpr u32 INVALID_QUEUE = ~0U;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, Intel Corporation
|
||||
* Copyright (c) 2015-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -426,6 +426,8 @@ struct RoseEngine {
|
||||
|
||||
u32 eodProgramOffset; //!< EOD program, otherwise 0.
|
||||
u32 flushCombProgramOffset; /**< FlushCombination program, otherwise 0 */
|
||||
u32 lastFlushCombProgramOffset; /**< LastFlushCombination program,
|
||||
* otherwise 0 */
|
||||
|
||||
u32 lastByteHistoryIterOffset; // if non-zero
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, Intel Corporation
|
||||
* Copyright (c) 2015-2019, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -201,7 +201,14 @@ enum RoseInstructionCode {
|
||||
/** \brief Mark as exhausted instead of report while quiet. */
|
||||
ROSE_INSTR_SET_EXHAUST,
|
||||
|
||||
LAST_ROSE_INSTRUCTION = ROSE_INSTR_SET_EXHAUST //!< Sentinel.
|
||||
/**
|
||||
* \brief Calculate any combination's logical value if none of its
|
||||
* sub-expression matches until EOD, then check if compliant with any
|
||||
* logical constraints.
|
||||
*/
|
||||
ROSE_INSTR_LAST_FLUSH_COMBINATION,
|
||||
|
||||
LAST_ROSE_INSTRUCTION = ROSE_INSTR_LAST_FLUSH_COMBINATION //!< Sentinel.
|
||||
};
|
||||
|
||||
struct ROSE_STRUCT_END {
|
||||
@@ -674,4 +681,8 @@ struct ROSE_STRUCT_SET_EXHAUST {
|
||||
u8 code; //!< From enum RoseInstructionCode.
|
||||
u32 ekey; //!< Exhaustion key.
|
||||
};
|
||||
|
||||
struct ROSE_STRUCT_LAST_FLUSH_COMBINATION {
|
||||
u8 code; //!< From enum RoseInstructionCode.
|
||||
};
|
||||
#endif // ROSE_ROSE_PROGRAM_H
|
||||
|
||||
Reference in New Issue
Block a user