[nginx] svn commit: r4389 - in trunk: auto auto/lib/pcre src/core
vbart at nginx.com
vbart at nginx.com
Mon Dec 26 13:10:36 UTC 2011
Author: vbart
Date: 2011-12-26 13:10:36 +0000 (Mon, 26 Dec 2011)
New Revision: 4389
Log:
Added support for regex study and PCRE JIT (ticket #41) optimizations on
configuration phase.
Modified:
trunk/auto/lib/pcre/conf
trunk/auto/lib/pcre/make
trunk/auto/modules
trunk/auto/options
trunk/auto/sources
trunk/src/core/ngx_regex.c
trunk/src/core/ngx_regex.h
Modified: trunk/auto/lib/pcre/conf
===================================================================
--- trunk/auto/lib/pcre/conf 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/auto/lib/pcre/conf 2011-12-26 13:10:36 UTC (rev 4389)
@@ -4,8 +4,6 @@
if [ $PCRE != NONE ]; then
CORE_INCS="$CORE_INCS $PCRE"
- CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
- CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
case "$NGX_CC_NAME" in
@@ -81,6 +79,12 @@
esac
+
+ if [ $PCRE_JIT = YES ]; then
+ have=NGX_HAVE_PCRE_JIT . auto/have
+ PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
+ fi
+
else
if [ "$NGX_PLATFORM" != win32 ]; then
@@ -156,12 +160,23 @@
fi
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_LIBS="$CORE_LIBS $ngx_feature_libs"
PCRE=YES
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
if [ $PCRE != YES ]; then
Modified: trunk/auto/lib/pcre/make
===================================================================
--- trunk/auto/lib/pcre/make 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/auto/lib/pcre/make 2011-12-26 13:10:36 UTC (rev 4389)
@@ -50,7 +50,7 @@
cd $PCRE \\
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
&& CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
- ./configure --disable-shared
+ ./configure --disable-shared $PCRE_CONF_OPT
$PCRE/.libs/libpcre.a: $PCRE/Makefile
cd $PCRE \\
Modified: trunk/auto/modules
===================================================================
--- trunk/auto/modules 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/auto/modules 2011-12-26 13:10:36 UTC (rev 4389)
@@ -396,6 +396,12 @@
CORE_SRCS="$CORE_SRCS $OPENSSL_SRCS"
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
modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
$HTTP_HEADERS_FILTER_MODULE \
Modified: trunk/auto/options
===================================================================
--- trunk/auto/options 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/auto/options 2011-12-26 13:10:36 UTC (rev 4389)
@@ -111,6 +111,8 @@
USE_PCRE=NO
PCRE=NONE
PCRE_OPT=
+PCRE_CONF_OPT=
+PCRE_JIT=NO
USE_OPENSSL=NO
OPENSSL=NONE
@@ -274,6 +276,7 @@
--with-pcre) USE_PCRE=YES ;;
--with-pcre=*) PCRE="$value" ;;
--with-pcre-opt=*) PCRE_OPT="$value" ;;
+ --with-pcre-jit) PCRE_JIT=YES ;;
--with-openssl=*) OPENSSL="$value" ;;
--with-openssl-opt=*) OPENSSL_OPT="$value" ;;
@@ -421,6 +424,7 @@
--with-pcre force PCRE library usage
--with-pcre=DIR set path to PCRE library sources
--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-opt=OPTIONS set additional build options for md5
Modified: trunk/auto/sources
===================================================================
--- trunk/auto/sources 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/auto/sources 2011-12-26 13:10:36 UTC (rev 4389)
@@ -69,6 +69,7 @@
src/core/ngx_crypt.c"
+REGEX_MODULE=ngx_regex_module
REGEX_DEPS=src/core/ngx_regex.h
REGEX_SRCS=src/core/ngx_regex.c
Modified: trunk/src/core/ngx_regex.c
===================================================================
--- trunk/src/core/ngx_regex.c 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/src/core/ngx_regex.c 2011-12-26 13:10:36 UTC (rev 4389)
@@ -8,11 +8,61 @@
#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_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_list_t *ngx_pcre_studies;
void
@@ -62,10 +112,11 @@
ngx_int_t
ngx_regex_compile(ngx_regex_compile_t *rc)
{
- int n, erroff;
- char *p;
- const char *errstr;
- ngx_regex_t *re;
+ int n, erroff;
+ char *p;
+ pcre *re;
+ const char *errstr;
+ ngx_regex_elt_t *elt;
ngx_regex_malloc_init(rc->pool);
@@ -92,8 +143,25 @@
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);
if (n < 0) {
p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
@@ -203,3 +271,140 @@
{
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;
+}
Modified: trunk/src/core/ngx_regex.h
===================================================================
--- trunk/src/core/ngx_regex.h 2011-12-26 11:33:11 UTC (rev 4388)
+++ trunk/src/core/ngx_regex.h 2011-12-26 13:10:36 UTC (rev 4389)
@@ -18,9 +18,13 @@
#define NGX_REGEX_CASELESS PCRE_CASELESS
-typedef pcre ngx_regex_t;
+typedef struct {
+ pcre *pcre;
+ pcre_extra *extra;
+} ngx_regex_t;
+
typedef struct {
ngx_str_t pattern;
ngx_pool_t *pool;
@@ -45,7 +49,7 @@
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
#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)
#define ngx_regex_exec_n "pcre_exec()"
More information about the nginx-devel
mailing list