mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
Added support for regex study and PCRE JIT (ticket #41) optimizations on
configuration phase.
This commit is contained in:
parent
947bdfa7fe
commit
bc5191c7bc
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
if [ $PCRE != NONE ]; then
|
if [ $PCRE != NONE ]; then
|
||||||
CORE_INCS="$CORE_INCS $PCRE"
|
CORE_INCS="$CORE_INCS $PCRE"
|
||||||
CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
|
|
||||||
CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
|
|
||||||
|
|
||||||
case "$NGX_CC_NAME" in
|
case "$NGX_CC_NAME" in
|
||||||
|
|
||||||
@ -81,6 +79,12 @@ if [ $PCRE != NONE ]; then
|
|||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
if [ $PCRE_JIT = YES ]; then
|
||||||
|
have=NGX_HAVE_PCRE_JIT . auto/have
|
||||||
|
PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
if [ "$NGX_PLATFORM" != win32 ]; then
|
if [ "$NGX_PLATFORM" != win32 ]; then
|
||||||
@ -156,12 +160,23 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $ngx_found = yes ]; then
|
if [ $ngx_found = yes ]; then
|
||||||
CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
|
|
||||||
CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
|
|
||||||
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
||||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||||
PCRE=YES
|
PCRE=YES
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $PCRE == YES ]; then
|
||||||
|
ngx_feature="PCRE JIT support"
|
||||||
|
ngx_feature_name="NGX_HAVE_PCRE_JIT"
|
||||||
|
ngx_feature_test="int jit = 0;
|
||||||
|
pcre_config(PCRE_CONFIG_JIT, &jit);
|
||||||
|
if (jit != 1) return 1;"
|
||||||
|
. auto/feature
|
||||||
|
|
||||||
|
if [ $ngx_found = yes ]; then
|
||||||
|
PCRE_JIT=YES
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $PCRE != YES ]; then
|
if [ $PCRE != YES ]; then
|
||||||
|
@ -50,7 +50,7 @@ $PCRE/Makefile: $NGX_MAKEFILE
|
|||||||
cd $PCRE \\
|
cd $PCRE \\
|
||||||
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
|
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
|
||||||
&& CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
|
&& CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
|
||||||
./configure --disable-shared
|
./configure --disable-shared $PCRE_CONF_OPT
|
||||||
|
|
||||||
$PCRE/.libs/libpcre.a: $PCRE/Makefile
|
$PCRE/.libs/libpcre.a: $PCRE/Makefile
|
||||||
cd $PCRE \\
|
cd $PCRE \\
|
||||||
|
@ -396,6 +396,12 @@ if [ $USE_OPENSSL = YES ]; then
|
|||||||
CORE_SRCS="$CORE_SRCS $OPENSSL_SRCS"
|
CORE_SRCS="$CORE_SRCS $OPENSSL_SRCS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $USE_PCRE = YES ]; then
|
||||||
|
modules="$modules $REGEX_MODULE"
|
||||||
|
CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
|
||||||
|
CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $HTTP = YES ]; then
|
if [ $HTTP = YES ]; then
|
||||||
modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
|
modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
|
||||||
$HTTP_HEADERS_FILTER_MODULE \
|
$HTTP_HEADERS_FILTER_MODULE \
|
||||||
|
@ -111,6 +111,8 @@ NGX_ADDONS=
|
|||||||
USE_PCRE=NO
|
USE_PCRE=NO
|
||||||
PCRE=NONE
|
PCRE=NONE
|
||||||
PCRE_OPT=
|
PCRE_OPT=
|
||||||
|
PCRE_CONF_OPT=
|
||||||
|
PCRE_JIT=NO
|
||||||
|
|
||||||
USE_OPENSSL=NO
|
USE_OPENSSL=NO
|
||||||
OPENSSL=NONE
|
OPENSSL=NONE
|
||||||
@ -274,6 +276,7 @@ use the \"--without-http_limit_conn_module\" option instead"
|
|||||||
--with-pcre) USE_PCRE=YES ;;
|
--with-pcre) USE_PCRE=YES ;;
|
||||||
--with-pcre=*) PCRE="$value" ;;
|
--with-pcre=*) PCRE="$value" ;;
|
||||||
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
||||||
|
--with-pcre-jit) PCRE_JIT=YES ;;
|
||||||
|
|
||||||
--with-openssl=*) OPENSSL="$value" ;;
|
--with-openssl=*) OPENSSL="$value" ;;
|
||||||
--with-openssl-opt=*) OPENSSL_OPT="$value" ;;
|
--with-openssl-opt=*) OPENSSL_OPT="$value" ;;
|
||||||
@ -421,6 +424,7 @@ cat << END
|
|||||||
--with-pcre force PCRE library usage
|
--with-pcre force PCRE library usage
|
||||||
--with-pcre=DIR set path to PCRE library sources
|
--with-pcre=DIR set path to PCRE library sources
|
||||||
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
||||||
|
--with-pcre-jit build PCRE with JIT compilation support
|
||||||
|
|
||||||
--with-md5=DIR set path to md5 library sources
|
--with-md5=DIR set path to md5 library sources
|
||||||
--with-md5-opt=OPTIONS set additional build options for md5
|
--with-md5-opt=OPTIONS set additional build options for md5
|
||||||
|
@ -69,6 +69,7 @@ CORE_SRCS="src/core/nginx.c \
|
|||||||
src/core/ngx_crypt.c"
|
src/core/ngx_crypt.c"
|
||||||
|
|
||||||
|
|
||||||
|
REGEX_MODULE=ngx_regex_module
|
||||||
REGEX_DEPS=src/core/ngx_regex.h
|
REGEX_DEPS=src/core/ngx_regex.h
|
||||||
REGEX_SRCS=src/core/ngx_regex.c
|
REGEX_SRCS=src/core/ngx_regex.c
|
||||||
|
|
||||||
|
@ -8,11 +8,61 @@
|
|||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_flag_t pcre_jit;
|
||||||
|
} ngx_regex_conf_t;
|
||||||
|
|
||||||
|
|
||||||
static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
|
static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
|
||||||
static void ngx_libc_cdecl ngx_regex_free(void *p);
|
static void ngx_libc_cdecl ngx_regex_free(void *p);
|
||||||
|
|
||||||
|
static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
|
||||||
|
|
||||||
|
static void *ngx_regex_create_conf(ngx_cycle_t *cycle);
|
||||||
|
static char *ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf);
|
||||||
|
|
||||||
|
static char *ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data);
|
||||||
|
static ngx_conf_post_t ngx_regex_pcre_jit_post = { ngx_regex_pcre_jit };
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_command_t ngx_regex_commands[] = {
|
||||||
|
|
||||||
|
{ ngx_string("pcre_jit"),
|
||||||
|
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
|
||||||
|
ngx_conf_set_flag_slot,
|
||||||
|
0,
|
||||||
|
offsetof(ngx_regex_conf_t, pcre_jit),
|
||||||
|
&ngx_regex_pcre_jit_post },
|
||||||
|
|
||||||
|
ngx_null_command
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_core_module_t ngx_regex_module_ctx = {
|
||||||
|
ngx_string("regex"),
|
||||||
|
ngx_regex_create_conf,
|
||||||
|
ngx_regex_init_conf
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ngx_module_t ngx_regex_module = {
|
||||||
|
NGX_MODULE_V1,
|
||||||
|
&ngx_regex_module_ctx, /* module context */
|
||||||
|
ngx_regex_commands, /* module directives */
|
||||||
|
NGX_CORE_MODULE, /* module type */
|
||||||
|
NULL, /* init master */
|
||||||
|
ngx_regex_module_init, /* init module */
|
||||||
|
NULL, /* init process */
|
||||||
|
NULL, /* init thread */
|
||||||
|
NULL, /* exit thread */
|
||||||
|
NULL, /* exit process */
|
||||||
|
NULL, /* exit master */
|
||||||
|
NGX_MODULE_V1_PADDING
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static ngx_pool_t *ngx_pcre_pool;
|
static ngx_pool_t *ngx_pcre_pool;
|
||||||
|
static ngx_list_t *ngx_pcre_studies;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -62,10 +112,11 @@ ngx_regex_malloc_done(void)
|
|||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_regex_compile(ngx_regex_compile_t *rc)
|
ngx_regex_compile(ngx_regex_compile_t *rc)
|
||||||
{
|
{
|
||||||
int n, erroff;
|
int n, erroff;
|
||||||
char *p;
|
char *p;
|
||||||
const char *errstr;
|
pcre *re;
|
||||||
ngx_regex_t *re;
|
const char *errstr;
|
||||||
|
ngx_regex_elt_t *elt;
|
||||||
|
|
||||||
ngx_regex_malloc_init(rc->pool);
|
ngx_regex_malloc_init(rc->pool);
|
||||||
|
|
||||||
@ -92,7 +143,24 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc->regex = re;
|
rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t));
|
||||||
|
if (rc->regex == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->regex->pcre = re;
|
||||||
|
|
||||||
|
/* do not study at runtime */
|
||||||
|
|
||||||
|
if (ngx_pcre_studies != NULL) {
|
||||||
|
elt = ngx_list_push(ngx_pcre_studies);
|
||||||
|
if (elt == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
elt->regex = rc->regex;
|
||||||
|
elt->name = rc->pattern.data;
|
||||||
|
}
|
||||||
|
|
||||||
n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
|
n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
@ -203,3 +271,140 @@ ngx_regex_free(void *p)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_regex_module_init(ngx_cycle_t *cycle)
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
const char *errstr;
|
||||||
|
ngx_uint_t i;
|
||||||
|
ngx_list_part_t *part;
|
||||||
|
ngx_regex_elt_t *elts;
|
||||||
|
|
||||||
|
opt = 0;
|
||||||
|
|
||||||
|
#if (NGX_HAVE_PCRE_JIT)
|
||||||
|
{
|
||||||
|
ngx_regex_conf_t *rcf;
|
||||||
|
|
||||||
|
rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
|
||||||
|
|
||||||
|
if (rcf->pcre_jit) {
|
||||||
|
opt = PCRE_STUDY_JIT_COMPILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ngx_regex_malloc_init(cycle->pool);
|
||||||
|
|
||||||
|
part = &ngx_pcre_studies->part;
|
||||||
|
elts = part->elts;
|
||||||
|
|
||||||
|
for (i = 0 ; /* void */ ; i++) {
|
||||||
|
|
||||||
|
if (i >= part->nelts) {
|
||||||
|
if (part->next == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
part = part->next;
|
||||||
|
elts = part->elts;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
elts[i].regex->extra = pcre_study(elts[i].regex->pcre, opt, &errstr);
|
||||||
|
|
||||||
|
if (errstr != NULL) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||||
|
"pcre_study() failed: %s in \"%s\"",
|
||||||
|
errstr, elts[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (NGX_HAVE_PCRE_JIT)
|
||||||
|
if (opt & PCRE_STUDY_JIT_COMPILE) {
|
||||||
|
int jit, n;
|
||||||
|
|
||||||
|
jit = 0;
|
||||||
|
n = pcre_fullinfo(elts[i].regex->pcre, elts[i].regex->extra,
|
||||||
|
PCRE_INFO_JIT, &jit);
|
||||||
|
|
||||||
|
if (n != 0 || jit != 1) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
|
||||||
|
"JIT compiler does not support pattern: \"%s\"",
|
||||||
|
elts[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_regex_malloc_done();
|
||||||
|
|
||||||
|
ngx_pcre_studies = NULL;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
ngx_regex_create_conf(ngx_cycle_t *cycle)
|
||||||
|
{
|
||||||
|
ngx_regex_conf_t *rcf;
|
||||||
|
|
||||||
|
rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
|
||||||
|
if (rcf == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcf->pcre_jit = NGX_CONF_UNSET;
|
||||||
|
|
||||||
|
ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
|
||||||
|
if (ngx_pcre_studies == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||||
|
{
|
||||||
|
ngx_regex_conf_t *rcf = conf;
|
||||||
|
|
||||||
|
ngx_conf_init_value(rcf->pcre_jit, 0);
|
||||||
|
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data)
|
||||||
|
{
|
||||||
|
ngx_flag_t *fp = data;
|
||||||
|
|
||||||
|
if (*fp == 0) {
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (NGX_HAVE_PCRE_JIT)
|
||||||
|
{
|
||||||
|
int jit, r;
|
||||||
|
|
||||||
|
jit = 0;
|
||||||
|
r = pcre_config(PCRE_CONFIG_JIT, &jit);
|
||||||
|
|
||||||
|
if (r != 0 || jit != 1) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"PCRE library does not support JIT");
|
||||||
|
*fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"nginx was build without PCRE JIT support");
|
||||||
|
*fp = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
||||||
|
@ -18,7 +18,11 @@
|
|||||||
|
|
||||||
#define NGX_REGEX_CASELESS PCRE_CASELESS
|
#define NGX_REGEX_CASELESS PCRE_CASELESS
|
||||||
|
|
||||||
typedef pcre ngx_regex_t;
|
|
||||||
|
typedef struct {
|
||||||
|
pcre *pcre;
|
||||||
|
pcre_extra *extra;
|
||||||
|
} ngx_regex_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -45,7 +49,7 @@ void ngx_regex_init(void);
|
|||||||
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
|
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
|
||||||
|
|
||||||
#define ngx_regex_exec(re, s, captures, size) \
|
#define ngx_regex_exec(re, s, captures, size) \
|
||||||
pcre_exec(re, NULL, (const char *) (s)->data, (s)->len, 0, 0, \
|
pcre_exec(re->pcre, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
|
||||||
captures, size)
|
captures, size)
|
||||||
#define ngx_regex_exec_n "pcre_exec()"
|
#define ngx_regex_exec_n "pcre_exec()"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user