mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-09-30 19:47:43 +03:00
Initial commit of Hyperscan
This commit is contained in:
407
src/smallwrite/smallwrite_build.cpp
Normal file
407
src/smallwrite/smallwrite_build.cpp
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "smallwrite/smallwrite_build.h"
|
||||
|
||||
#include "grey.h"
|
||||
#include "ue2common.h"
|
||||
#include "nfa/mcclellancompile.h"
|
||||
#include "nfa/mcclellancompile_util.h"
|
||||
#include "nfa/nfa_internal.h"
|
||||
#include "nfa/rdfa_merge.h"
|
||||
#include "nfagraph/ng.h"
|
||||
#include "nfagraph/ng_holder.h"
|
||||
#include "nfagraph/ng_mcclellan.h"
|
||||
#include "nfagraph/ng_util.h"
|
||||
#include "nfagraph/ng_width.h"
|
||||
#include "smallwrite/smallwrite_internal.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/charreach.h"
|
||||
#include "util/compile_context.h"
|
||||
#include "util/container.h"
|
||||
#include "util/make_unique.h"
|
||||
#include "util/ue2string.h"
|
||||
#include "util/verify_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
#define LITERAL_MERGE_CHUNK_SIZE 25
|
||||
#define DFA_MERGE_MAX_STATES 8000
|
||||
|
||||
namespace { // unnamed
|
||||
|
||||
// Concrete impl class
|
||||
class SmallWriteBuildImpl : public SmallWriteBuild {
|
||||
public:
|
||||
SmallWriteBuildImpl(const ReportManager &rm, const CompileContext &cc);
|
||||
|
||||
// Construct a runtime implementation.
|
||||
aligned_unique_ptr<SmallWriteEngine> build(u32 roseQuality) override;
|
||||
|
||||
void add(const NGWrapper &w) override;
|
||||
void add(const ue2_literal &literal, ReportID r) override;
|
||||
|
||||
bool determiniseLiterals();
|
||||
|
||||
const ReportManager &rm;
|
||||
const CompileContext &cc;
|
||||
|
||||
unique_ptr<raw_dfa> rdfa;
|
||||
vector<pair<ue2_literal, ReportID> > cand_literals;
|
||||
bool poisoned;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
SmallWriteBuild::~SmallWriteBuild() { }
|
||||
|
||||
SmallWriteBuildImpl::SmallWriteBuildImpl(const ReportManager &rm_in,
|
||||
const CompileContext &cc_in)
|
||||
: rm(rm_in), cc(cc_in),
|
||||
/* small write is block mode only */
|
||||
poisoned(!cc.grey.allowSmallWrite || cc.streaming) {
|
||||
}
|
||||
|
||||
void SmallWriteBuildImpl::add(const NGWrapper &w) {
|
||||
// If the graph is poisoned (i.e. we can't build a SmallWrite version),
|
||||
// we don't even try.
|
||||
if (poisoned) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (w.som || w.min_length || isVacuous(w)) { /* cannot support in smwr */
|
||||
poisoned = true;
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("w=%p\n", &w);
|
||||
|
||||
// make a copy of the graph so that we can modify it for our purposes
|
||||
unique_ptr<NGHolder> h = cloneHolder(w);
|
||||
|
||||
reduceGraph(*h, SOM_NONE, w.utf8, cc);
|
||||
|
||||
// If the earliest match location is outside the small write region,
|
||||
// then we don't need to build a SmallWrite version.
|
||||
// However, we don't poison this case either, since it is simply a case,
|
||||
// where we know the resulting graph won't match.
|
||||
if (findMinWidth(*h) > depth(cc.grey.smallWriteLargestBuffer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we can actually build the McClellan DFA
|
||||
assert(h->kind == NFA_OUTFIX);
|
||||
auto r = buildMcClellan(*h, &rm, cc.grey);
|
||||
|
||||
// If we couldn't build a McClellan DFA for this portion, we won't be able
|
||||
// build a smwr which represents the pattern set
|
||||
if (!r) {
|
||||
DEBUG_PRINTF("failed to determinise\n");
|
||||
poisoned = true;
|
||||
return;
|
||||
}
|
||||
|
||||
prune_overlong(*r, cc.grey.smallWriteLargestBuffer);
|
||||
|
||||
if (rdfa) {
|
||||
// do a merge of the new dfa with the existing dfa
|
||||
auto merged = mergeTwoDfas(rdfa.get(), r.get(), DFA_MERGE_MAX_STATES,
|
||||
&rm, cc.grey);
|
||||
if (!merged) {
|
||||
DEBUG_PRINTF("merge failed\n");
|
||||
poisoned = true;
|
||||
return;
|
||||
}
|
||||
DEBUG_PRINTF("merge succeeded, built %p\n", merged.get());
|
||||
rdfa = move(merged);
|
||||
} else {
|
||||
rdfa = move(r);
|
||||
}
|
||||
}
|
||||
|
||||
void SmallWriteBuildImpl::add(const ue2_literal &literal, ReportID r) {
|
||||
// If the graph is poisoned (i.e. we can't build a SmallWrite version),
|
||||
// we don't even try.
|
||||
if (poisoned) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (literal.length() > cc.grey.smallWriteLargestBuffer) {
|
||||
return; /* too long */
|
||||
}
|
||||
|
||||
cand_literals.push_back(make_pair(literal, r));
|
||||
}
|
||||
|
||||
static
|
||||
void lit_to_graph(NGHolder *h, const ue2_literal &literal, ReportID r) {
|
||||
NFAVertex u = h->startDs;
|
||||
for (const auto &c : literal) {
|
||||
NFAVertex v = add_vertex(*h);
|
||||
add_edge(u, v, *h);
|
||||
(*h)[v].char_reach = c;
|
||||
u = v;
|
||||
}
|
||||
(*h)[u].reports.insert(r);
|
||||
add_edge(u, h->accept, *h);
|
||||
}
|
||||
|
||||
bool SmallWriteBuildImpl::determiniseLiterals() {
|
||||
DEBUG_PRINTF("handling literals\n");
|
||||
assert(!poisoned);
|
||||
|
||||
if (cand_literals.empty()) {
|
||||
return true; /* nothing to do */
|
||||
}
|
||||
|
||||
vector<unique_ptr<raw_dfa> > temp_dfas;
|
||||
|
||||
for (const auto &cand : cand_literals) {
|
||||
NGHolder h;
|
||||
DEBUG_PRINTF("determinising %s\n", dumpString(cand.first).c_str());
|
||||
lit_to_graph(&h, cand.first, cand.second);
|
||||
temp_dfas.push_back(buildMcClellan(h, &rm, cc.grey));
|
||||
|
||||
// If we couldn't build a McClellan DFA for this portion, then we
|
||||
// can't SmallWrite optimize the entire graph, so we can't
|
||||
// optimize any of it
|
||||
if (!temp_dfas.back()) {
|
||||
DEBUG_PRINTF("failed to determinise\n");
|
||||
poisoned = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rdfa && temp_dfas.size() == 1) {
|
||||
/* no need to merge there is only one dfa */
|
||||
rdfa = move(temp_dfas[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* do a merge of the new dfas */
|
||||
|
||||
vector<const raw_dfa *> to_merge;
|
||||
|
||||
if (rdfa) {/* also include the existing dfa */
|
||||
to_merge.push_back(rdfa.get());
|
||||
}
|
||||
|
||||
for (const auto &d : temp_dfas) {
|
||||
to_merge.push_back(d.get());
|
||||
}
|
||||
|
||||
assert(to_merge.size() > 1);
|
||||
|
||||
while (to_merge.size() > LITERAL_MERGE_CHUNK_SIZE) {
|
||||
vector<const raw_dfa *> small_merge;
|
||||
small_merge.insert(small_merge.end(), to_merge.begin(),
|
||||
to_merge.begin() + LITERAL_MERGE_CHUNK_SIZE);
|
||||
|
||||
temp_dfas.push_back(
|
||||
mergeAllDfas(small_merge, DFA_MERGE_MAX_STATES, &rm, cc.grey));
|
||||
|
||||
if (!temp_dfas.back()) {
|
||||
DEBUG_PRINTF("merge failed\n");
|
||||
poisoned = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
to_merge.erase(to_merge.begin(),
|
||||
to_merge.begin() + LITERAL_MERGE_CHUNK_SIZE);
|
||||
to_merge.push_back(temp_dfas.back().get());
|
||||
}
|
||||
|
||||
auto merged = mergeAllDfas(to_merge, DFA_MERGE_MAX_STATES, &rm, cc.grey);
|
||||
|
||||
if (!merged) {
|
||||
DEBUG_PRINTF("merge failed\n");
|
||||
poisoned = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("merge succeeded, built %p\n", merged.get());
|
||||
|
||||
// Replace our only DFA with the merged one
|
||||
rdfa = move(merged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MAX_GOOD_ACCEL_DEPTH 4
|
||||
|
||||
static
|
||||
bool is_slow(const raw_dfa &rdfa, const set<dstate_id_t> &accel,
|
||||
u32 roseQuality) {
|
||||
/* we consider a dfa as slow if there is no way to quickly get into an accel
|
||||
* state/dead state. In these cases, it is more likely that we will be
|
||||
* running at our unaccelerated dfa speeds so the small write engine is only
|
||||
* competitive over a small region where start up costs are dominant. */
|
||||
|
||||
if (roseQuality) {
|
||||
return true;
|
||||
}
|
||||
|
||||
set<dstate_id_t> visited;
|
||||
set<dstate_id_t> next;
|
||||
set<dstate_id_t> curr;
|
||||
curr.insert(rdfa.start_anchored);
|
||||
|
||||
u32 ialpha_size = rdfa.getImplAlphaSize();
|
||||
|
||||
for (u32 i = 0; i < MAX_GOOD_ACCEL_DEPTH; i++) {
|
||||
next.clear();
|
||||
for (dstate_id_t s : curr) {
|
||||
if (contains(visited, s)) {
|
||||
continue;
|
||||
}
|
||||
visited.insert(s);
|
||||
if (s == DEAD_STATE || contains(accel, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < ialpha_size; j++) {
|
||||
next.insert(rdfa.states[s].next[j]);
|
||||
}
|
||||
}
|
||||
curr.swap(next);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
aligned_unique_ptr<NFA> prepEngine(raw_dfa &rdfa, u32 roseQuality,
|
||||
const CompileContext &cc, u32 *start_offset,
|
||||
u32 *small_region) {
|
||||
*start_offset = remove_leading_dots(rdfa);
|
||||
|
||||
// Unleash the McClellan!
|
||||
set<dstate_id_t> accel_states;
|
||||
|
||||
auto nfa = mcclellanCompile(rdfa, cc, &accel_states);
|
||||
if (!nfa) {
|
||||
DEBUG_PRINTF("mcclellan compile failed for smallwrite NFA\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (is_slow(rdfa, accel_states, roseQuality)) {
|
||||
*small_region = cc.grey.smallWriteLargestBufferBad;
|
||||
if (*small_region <= *start_offset) {
|
||||
return nullptr;
|
||||
}
|
||||
prune_overlong(rdfa, *small_region - *start_offset);
|
||||
if (rdfa.start_anchored == DEAD_STATE) {
|
||||
DEBUG_PRINTF("all patterns pruned out\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nfa = mcclellanCompile(rdfa, cc, &accel_states);
|
||||
if (!nfa) {
|
||||
DEBUG_PRINTF("mcclellan compile failed for smallwrite NFA\n");
|
||||
assert(0); /* we were able to build orig dfa but not the trimmed? */
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
*small_region = cc.grey.smallWriteLargestBuffer;
|
||||
}
|
||||
|
||||
assert(isMcClellanType(nfa->type));
|
||||
if (nfa->length > cc.grey.limitSmallWriteOutfixSize
|
||||
|| nfa->length > cc.grey.limitDFASize) {
|
||||
DEBUG_PRINTF("smallwrite outfix size too large\n");
|
||||
return nullptr; /* this is just a soft failure - don't build smwr */
|
||||
}
|
||||
|
||||
nfa->queueIndex = 0; /* dummy, small write API does not use queue */
|
||||
return nfa;
|
||||
}
|
||||
|
||||
// SmallWriteBuild factory
|
||||
unique_ptr<SmallWriteBuild> makeSmallWriteBuilder(const ReportManager &rm,
|
||||
const CompileContext &cc) {
|
||||
return ue2::make_unique<SmallWriteBuildImpl>(rm, cc);
|
||||
}
|
||||
|
||||
aligned_unique_ptr<SmallWriteEngine>
|
||||
SmallWriteBuildImpl::build(u32 roseQuality) {
|
||||
if (!rdfa && cand_literals.empty()) {
|
||||
DEBUG_PRINTF("no smallwrite engine\n");
|
||||
poisoned = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (poisoned) {
|
||||
DEBUG_PRINTF("some pattern could not be made into a smallwrite dfa\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!determiniseLiterals()) {
|
||||
DEBUG_PRINTF("some literal could not be made into a smallwrite dfa\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("building rdfa %p\n", rdfa.get());
|
||||
|
||||
u32 start_offset;
|
||||
u32 small_region;
|
||||
auto nfa = prepEngine(*rdfa, roseQuality, cc, &start_offset, &small_region);
|
||||
if (!nfa) {
|
||||
DEBUG_PRINTF("some smallwrite outfix could not be prepped\n");
|
||||
/* just skip the smallwrite optimization */
|
||||
poisoned = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
u32 size = sizeof(SmallWriteEngine) + nfa->length;
|
||||
auto smwr = aligned_zmalloc_unique<SmallWriteEngine>(size);
|
||||
|
||||
smwr->size = size;
|
||||
smwr->start_offset = start_offset;
|
||||
smwr->largestBuffer = small_region;
|
||||
|
||||
/* copy in nfa after the smwr */
|
||||
assert(ISALIGNED_CL(smwr.get() + 1));
|
||||
memcpy(smwr.get() + 1, nfa.get(), nfa->length);
|
||||
|
||||
DEBUG_PRINTF("smallwrite done %p\n", smwr.get());
|
||||
return smwr;
|
||||
}
|
||||
|
||||
size_t smwrSize(const SmallWriteEngine *smwr) {
|
||||
assert(smwr);
|
||||
return smwr->size;
|
||||
}
|
||||
|
||||
} // namespace ue2
|
74
src/smallwrite/smallwrite_build.h
Normal file
74
src/smallwrite/smallwrite_build.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SMWR_BUILD_H
|
||||
#define SMWR_BUILD_H
|
||||
|
||||
/**
|
||||
* SmallWrite Build interface. Everything you ever needed to feed literals in
|
||||
* and get a SmallWriteEngine out. This header should be everything needed by
|
||||
* the rest of UE2.
|
||||
*/
|
||||
|
||||
#include "ue2common.h"
|
||||
#include "util/alloc.h"
|
||||
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
|
||||
struct SmallWriteEngine;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
struct CompileContext;
|
||||
struct ue2_literal;
|
||||
class NGWrapper;
|
||||
class ReportManager;
|
||||
|
||||
// Abstract interface intended for callers from elsewhere in the tree, real
|
||||
// underlying implementation is SmallWriteBuildImpl in smwr_build_impl.h.
|
||||
class SmallWriteBuild : boost::noncopyable {
|
||||
public:
|
||||
// Destructor
|
||||
virtual ~SmallWriteBuild();
|
||||
|
||||
// Construct a runtime implementation.
|
||||
virtual ue2::aligned_unique_ptr<SmallWriteEngine> build(u32 roseQuality) = 0;
|
||||
|
||||
virtual void add(const NGWrapper &w) = 0;
|
||||
virtual void add(const ue2_literal &literal, ReportID r) = 0;
|
||||
};
|
||||
|
||||
// Construct a usable SmallWrite builder.
|
||||
std::unique_ptr<SmallWriteBuild> makeSmallWriteBuilder(const ReportManager &rm,
|
||||
const CompileContext &cc);
|
||||
|
||||
size_t smwrSize(const SmallWriteEngine *t);
|
||||
|
||||
} // namespace ue2
|
||||
|
||||
#endif // SMWR_BUILD_H
|
90
src/smallwrite/smallwrite_dump.cpp
Normal file
90
src/smallwrite/smallwrite_dump.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "smallwrite_dump.h"
|
||||
#include "smallwrite_internal.h"
|
||||
#include "ue2common.h"
|
||||
#include "nfa/nfa_build_util.h"
|
||||
#include "nfa/nfa_dump_api.h"
|
||||
#include "nfa/nfa_internal.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#ifndef DUMP_SUPPORT
|
||||
#error No dump support!
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
void smwrDumpText(const SmallWriteEngine *smwr, FILE *f) {
|
||||
if (!smwr) {
|
||||
fprintf(f, "<< no smallwrite >>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const struct NFA *n = getSmwrNfa(smwr);
|
||||
|
||||
fprintf(f, "SmallWrite:\n\n");
|
||||
fprintf(f, "%s\n", describe(*n).c_str());
|
||||
fprintf(f, "States: %u\n", n->nPositions);
|
||||
fprintf(f, "Length: %u\n", n->length);
|
||||
fprintf(f, "Largest Short Buffer: %u\n", smwr->largestBuffer);
|
||||
fprintf(f, "Start Offset: %u\n", smwr->start_offset);
|
||||
}
|
||||
|
||||
void smwrDumpNFA(const SmallWriteEngine *smwr, bool dump_raw,
|
||||
const string &base) {
|
||||
if (!smwr) {
|
||||
DEBUG_PRINTF("no smallwrite\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const struct NFA *n = getSmwrNfa(smwr);
|
||||
FILE *f;
|
||||
|
||||
f = fopen((base + "smallwrite_nfa.dot").c_str(), "w");
|
||||
nfaDumpDot(n, f);
|
||||
fclose(f);
|
||||
|
||||
f = fopen((base + "smallwrite_nfa.txt").c_str(), "w");
|
||||
nfaDumpText(n, f);
|
||||
fclose(f);
|
||||
|
||||
if (dump_raw) {
|
||||
f = fopen((base + "smallwrite_nfa.raw").c_str(), "w");
|
||||
fwrite(n, 1, n->length, f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ue2
|
47
src/smallwrite/smallwrite_dump.h
Normal file
47
src/smallwrite/smallwrite_dump.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SMWR_DUMP_H
|
||||
#define SMWR_DUMP_H
|
||||
#ifdef DUMP_SUPPORT
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
struct SmallWriteEngine;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
void smwrDumpText(const SmallWriteEngine *smwr, FILE *f);
|
||||
void smwrDumpNFA(const SmallWriteEngine *smwr, bool dump_raw,
|
||||
const std::string &base);
|
||||
|
||||
} // namespace ue2
|
||||
|
||||
#endif
|
||||
#endif
|
53
src/smallwrite/smallwrite_internal.h
Normal file
53
src/smallwrite/smallwrite_internal.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SMALLWRITE_INTERNAL_H
|
||||
#define SMALLWRITE_INTERNAL_H
|
||||
|
||||
#include "ue2common.h"
|
||||
|
||||
// Runtime structure header for SmallWrite.
|
||||
struct ALIGN_CL_DIRECTIVE SmallWriteEngine {
|
||||
u32 largestBuffer; /**< largest buffer that can be considered small write */
|
||||
u32 start_offset; /**< where to start scanning in the buffer. */
|
||||
u32 size; /**< size of the small write engine in bytes (including the nfa) */
|
||||
};
|
||||
|
||||
struct NFA;
|
||||
|
||||
static really_inline
|
||||
const struct NFA *getSmwrNfa(const struct SmallWriteEngine *smwr) {
|
||||
assert(smwr);
|
||||
const struct NFA *n
|
||||
= (const struct NFA *)((const char *)smwr + sizeof(*smwr));
|
||||
assert(ISALIGNED_CL(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif // SMALLWRITE_INTERNAL_H
|
||||
|
Reference in New Issue
Block a user