mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-09-29 19:24:25 +03:00
Fat runtime
This commit is contained in:
@@ -29,8 +29,10 @@
|
||||
/** \file
|
||||
* \brief Compiler front-end interface.
|
||||
*/
|
||||
#include "allocator.h"
|
||||
#include "asserts.h"
|
||||
#include "compiler.h"
|
||||
#include "crc32.h"
|
||||
#include "database.h"
|
||||
#include "grey.h"
|
||||
#include "hs_internal.h"
|
||||
@@ -321,6 +323,45 @@ platform_t target_to_platform(const target_t &target_info) {
|
||||
return p;
|
||||
}
|
||||
|
||||
/** \brief Encapsulate the given bytecode (RoseEngine) in a newly-allocated
|
||||
* \ref hs_database, ensuring that it is padded correctly to give cacheline
|
||||
* alignment. */
|
||||
static
|
||||
hs_database_t *dbCreate(const char *in_bytecode, size_t len, u64a platform) {
|
||||
size_t db_len = sizeof(struct hs_database) + len;
|
||||
DEBUG_PRINTF("db size %zu\n", db_len);
|
||||
DEBUG_PRINTF("db platform %llx\n", platform);
|
||||
|
||||
struct hs_database *db = (struct hs_database *)hs_database_alloc(db_len);
|
||||
if (hs_check_alloc(db) != HS_SUCCESS) {
|
||||
hs_database_free(db);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// So that none of our database is uninitialized
|
||||
memset(db, 0, db_len);
|
||||
|
||||
// we need to align things manually
|
||||
size_t shift = (uintptr_t)db->bytes & 0x3f;
|
||||
DEBUG_PRINTF("shift is %zu\n", shift);
|
||||
|
||||
db->bytecode = offsetof(struct hs_database, bytes) - shift;
|
||||
char *bytecode = (char *)db + db->bytecode;
|
||||
assert(ISALIGNED_CL(bytecode));
|
||||
|
||||
db->magic = HS_DB_MAGIC;
|
||||
db->version = HS_DB_VERSION;
|
||||
db->length = len;
|
||||
db->platform = platform;
|
||||
|
||||
// Copy bytecode
|
||||
memcpy(bytecode, in_bytecode, len);
|
||||
|
||||
db->crc32 = Crc32c_ComputeBuf(0, bytecode, db->length);
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
struct hs_database *build(NG &ng, unsigned int *length) {
|
||||
assert(length);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -348,43 +348,6 @@ hs_error_t dbIsValid(const hs_database_t *db) {
|
||||
return HS_SUCCESS;
|
||||
}
|
||||
|
||||
/** \brief Encapsulate the given bytecode (RoseEngine) in a newly-allocated
|
||||
* \ref hs_database, ensuring that it is padded correctly to give cacheline
|
||||
* alignment. */
|
||||
hs_database_t *dbCreate(const char *in_bytecode, size_t len, u64a platform) {
|
||||
size_t db_len = sizeof(struct hs_database) + len;
|
||||
DEBUG_PRINTF("db size %zu\n", db_len);
|
||||
DEBUG_PRINTF("db platform %llx\n", platform);
|
||||
|
||||
struct hs_database *db = (struct hs_database *)hs_database_alloc(db_len);
|
||||
if (hs_check_alloc(db) != HS_SUCCESS) {
|
||||
hs_database_free(db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// So that none of our database is uninitialized
|
||||
memset(db, 0, db_len);
|
||||
|
||||
// we need to align things manually
|
||||
size_t shift = (uintptr_t)db->bytes & 0x3f;
|
||||
DEBUG_PRINTF("shift is %zu\n", shift);
|
||||
|
||||
db->bytecode = offsetof(struct hs_database, bytes) - shift;
|
||||
char *bytecode = (char *)db + db->bytecode;
|
||||
assert(ISALIGNED_CL(bytecode));
|
||||
|
||||
db->magic = HS_DB_MAGIC;
|
||||
db->version = HS_DB_VERSION;
|
||||
db->length = len;
|
||||
db->platform = platform;
|
||||
|
||||
// Copy bytecode
|
||||
memcpy(bytecode, in_bytecode, len);
|
||||
|
||||
db->crc32 = Crc32c_ComputeBuf(0, bytecode, db->length);
|
||||
return db;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define SNPRINTF_COMPAT _snprintf
|
||||
#else
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -110,7 +110,6 @@ hs_error_t validDatabase(const hs_database_t *db) {
|
||||
}
|
||||
|
||||
hs_error_t dbIsValid(const struct hs_database *db);
|
||||
struct hs_database *dbCreate(const char *bytecode, size_t len, u64a platform);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
122
src/dispatcher.c
Normal file
122
src/dispatcher.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 "hs_common.h"
|
||||
#include "hs_runtime.h"
|
||||
#include "ue2common.h"
|
||||
#include "util/cpuid_flags.h"
|
||||
#include "util/join.h"
|
||||
|
||||
#define CREATE_DISPATCH(RTYPE, NAME, ...) \
|
||||
/* create defns */ \
|
||||
RTYPE JOIN(avx2_, NAME)(__VA_ARGS__); \
|
||||
RTYPE JOIN(corei7_, NAME)(__VA_ARGS__); \
|
||||
RTYPE JOIN(core2_, NAME)(__VA_ARGS__); \
|
||||
\
|
||||
/* error func */ \
|
||||
static inline RTYPE JOIN(error_, NAME)(__VA_ARGS__) { \
|
||||
return (RTYPE)HS_ARCH_ERROR; \
|
||||
} \
|
||||
\
|
||||
/* resolver */ \
|
||||
static void(*JOIN(resolve_, NAME)(void)) { \
|
||||
if (check_avx2()) { \
|
||||
return JOIN(avx2_, NAME); \
|
||||
} \
|
||||
if (check_sse42() && check_popcnt()) { \
|
||||
return JOIN(corei7_, NAME); \
|
||||
} \
|
||||
if (check_ssse3()) { \
|
||||
return JOIN(core2_, NAME); \
|
||||
} \
|
||||
/* anything else is fail */ \
|
||||
return JOIN(error_, NAME); \
|
||||
} \
|
||||
\
|
||||
/* function */ \
|
||||
RTYPE NAME(__VA_ARGS__) __attribute__((ifunc("resolve_" #NAME)))
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_scan, const hs_database_t *db, const char *data,
|
||||
unsigned length, unsigned flags, hs_scratch_t *scratch,
|
||||
match_event_handler onEvent, void *userCtx);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_stream_size, const hs_database_t *database,
|
||||
size_t *stream_size);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_database_size, const hs_database_t *db,
|
||||
size_t *size);
|
||||
CREATE_DISPATCH(hs_error_t, dbIsValid, const hs_database_t *db);
|
||||
CREATE_DISPATCH(hs_error_t, hs_free_database, hs_database_t *db);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_open_stream, const hs_database_t *db,
|
||||
unsigned int flags, hs_stream_t **stream);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_scan_stream, hs_stream_t *id, const char *data,
|
||||
unsigned int length, unsigned int flags, hs_scratch_t *scratch,
|
||||
match_event_handler onEvent, void *ctxt);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_close_stream, hs_stream_t *id,
|
||||
hs_scratch_t *scratch, match_event_handler onEvent, void *ctxt);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_scan_vector, const hs_database_t *db,
|
||||
const char *const *data, const unsigned int *length,
|
||||
unsigned int count, unsigned int flags, hs_scratch_t *scratch,
|
||||
match_event_handler onevent, void *context);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_database_info, const hs_database_t *db, char **info);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_copy_stream, hs_stream_t **to_id,
|
||||
const hs_stream_t *from_id);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_reset_stream, hs_stream_t *id,
|
||||
unsigned int flags, hs_scratch_t *scratch,
|
||||
match_event_handler onEvent, void *context);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_reset_and_copy_stream, hs_stream_t *to_id,
|
||||
const hs_stream_t *from_id, hs_scratch_t *scratch,
|
||||
match_event_handler onEvent, void *context);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_serialize_database, const hs_database_t *db,
|
||||
char **bytes, size_t *length);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_deserialize_database, const char *bytes,
|
||||
const size_t length, hs_database_t **db);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_deserialize_database_at, const char *bytes,
|
||||
const size_t length, hs_database_t *db);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_serialized_database_info, const char *bytes,
|
||||
size_t length, char **info);
|
||||
|
||||
CREATE_DISPATCH(hs_error_t, hs_serialized_database_size, const char *bytes,
|
||||
const size_t length, size_t *deserialized_size);
|
||||
|
||||
/** INTERNALS **/
|
||||
|
||||
CREATE_DISPATCH(u32, Crc32c_ComputeBuf, u32 inCrc32, const void *buf, size_t bufLen);
|
20
src/hs.cpp
20
src/hs.cpp
@@ -192,6 +192,14 @@ hs_compile_multi_int(const char *const *expressions, const unsigned *flags,
|
||||
return HS_COMPILER_ERROR;
|
||||
}
|
||||
|
||||
#if defined(FAT_RUNTIME)
|
||||
if (!check_ssse3()) {
|
||||
*db = nullptr;
|
||||
*comp_error = generateCompileError("Unsupported architecture", -1);
|
||||
return HS_ARCH_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!checkMode(mode, comp_error)) {
|
||||
*db = nullptr;
|
||||
assert(*comp_error); // set by checkMode.
|
||||
@@ -319,6 +327,13 @@ hs_error_t hs_expression_info_int(const char *expression, unsigned int flags,
|
||||
return HS_COMPILER_ERROR;
|
||||
}
|
||||
|
||||
#if defined(FAT_RUNTIME)
|
||||
if (!check_ssse3()) {
|
||||
*error = generateCompileError("Unsupported architecture", -1);
|
||||
return HS_ARCH_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!info) {
|
||||
*error = generateCompileError("Invalid parameter: info is NULL", -1);
|
||||
return HS_COMPILER_ERROR;
|
||||
@@ -426,6 +441,11 @@ hs_error_t hs_populate_platform(hs_platform_info_t *platform) {
|
||||
|
||||
extern "C" HS_PUBLIC_API
|
||||
hs_error_t hs_free_compile_error(hs_compile_error_t *error) {
|
||||
#if defined(FAT_RUNTIME)
|
||||
if (!check_ssse3()) {
|
||||
return HS_ARCH_ERROR;
|
||||
}
|
||||
#endif
|
||||
freeCompileError(error);
|
||||
return HS_SUCCESS;
|
||||
}
|
||||
|
@@ -519,6 +519,17 @@ const char *hs_version(void);
|
||||
*/
|
||||
#define HS_SCRATCH_IN_USE (-10)
|
||||
|
||||
/**
|
||||
* Unsupported CPU architecture.
|
||||
*
|
||||
* This error is returned when Hyperscan is able to detect that the current
|
||||
* system does not support the required instruction set.
|
||||
*
|
||||
* At a minimum, Hyperscan requires Supplemental Streaming SIMD Extensions 3
|
||||
* (SSSE3).
|
||||
*/
|
||||
#define HS_ARCH_ERROR (-11)
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -193,7 +193,8 @@ void createShuffleMasks(mcsheng *m, const dfa_info &info,
|
||||
}
|
||||
for (u32 i = 0; i < N_CHARS; i++) {
|
||||
assert(info.alpha_remap[i] != info.alpha_remap[TOP]);
|
||||
memcpy((u8*)&m->sheng_masks[i], (u8*)masks[info.alpha_remap[i]].data(), sizeof(m128));
|
||||
memcpy((u8 *)&m->sheng_masks[i],
|
||||
(u8 *)masks[info.alpha_remap[i]].data(), sizeof(m128));
|
||||
}
|
||||
m->sheng_end = sheng_end;
|
||||
m->sheng_accel_limit = sheng_end - 1;
|
||||
|
@@ -40,12 +40,14 @@
|
||||
#define SSSE3 (1 << 9)
|
||||
#define SSE4_1 (1 << 19)
|
||||
#define SSE4_2 (1 << 20)
|
||||
#define POPCNT (1 << 23)
|
||||
#define XSAVE (1 << 27)
|
||||
#define AVX (1 << 28)
|
||||
|
||||
// EDX
|
||||
#define FXSAVE (1 << 24)
|
||||
#define SSE (1 << 25)
|
||||
#define SSE2 (1 << 25)
|
||||
#define SSE2 (1 << 26)
|
||||
#define HTT (1 << 28)
|
||||
|
||||
// Structured Extended Feature Flags Enumeration Leaf ECX values
|
||||
@@ -87,7 +89,6 @@ u64a xgetbv(u32 op) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
int check_avx2(void) {
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _may_i_use_cpu_feature(_FEATURE_AVX2);
|
||||
@@ -137,6 +138,24 @@ u64a cpuid_flags(void) {
|
||||
return cap;
|
||||
}
|
||||
|
||||
int check_ssse3(void) {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
return !!(ecx & SSSE3);
|
||||
}
|
||||
|
||||
int check_sse42(void) {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
return !!(ecx & SSE4_2);
|
||||
}
|
||||
|
||||
int check_popcnt(void) {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
return !!(ecx & POPCNT);
|
||||
}
|
||||
|
||||
struct family_id {
|
||||
u32 full_family;
|
||||
u32 full_model;
|
||||
|
@@ -41,6 +41,11 @@ u64a cpuid_flags(void);
|
||||
|
||||
u32 cpuid_tune(void);
|
||||
|
||||
int check_avx2(void);
|
||||
int check_ssse3(void);
|
||||
int check_sse42(void);
|
||||
int check_popcnt(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@@ -61,6 +61,7 @@
|
||||
#error no intrinsics!
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
typedef __m128i m128;
|
||||
#else
|
||||
typedef struct ALIGN_DIRECTIVE {u64a hi; u64a lo;} m128;
|
||||
|
Reference in New Issue
Block a user