From: Rainer Jung Date: Tue, 24 Feb 2015 18:25:26 +0000 (+0000) Subject: Merge r1657685 from trunk: X-Git-Tag: 2.4.13~397 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3ce9d0180d2fe29195ce846795c0579d4d20a5e;p=thirdparty%2Fapache%2Fhttpd.git Merge r1657685 from trunk: core: Optimize string concatenation in expression parser when evaluating a string expression. We have a relatively small recursion limit of about 10 operations. This is a compilation limit (a define). It can be hit if many expr vars or function calls are concatenated in an expression that is evaluated as a string not as a boolean. The new optimization uses iteration instead of recursion and is very similar to the existing one, which optimizes consecutive concatenations in node2 of the tree. The new one optimizes consecutive concatenations in node 1. Submitted by: rjung Reviewed by: rjung, ylavic, covener Backported by: rjung git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1662075 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index ef32d263841..54f0c3b9914 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.13 + *) core: Optimize string concatenation in expression parser when evaluating + a string expression. [Rainer Jung] + *) acinclude.m4: Generate #LoadModule directive in default httpd.conf for every --enable-mpms-shared. PR 53882. [olli hauer , Yann Ylavic] diff --git a/STATUS b/STATUS index c623baaa0a5..05162f2978c 100644 --- a/STATUS +++ b/STATUS @@ -112,17 +112,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.4.x patch: trunk works (module CHANGES) +1: ylavic, wrowe, minfrin - * Expression parser: Optimize another concatenation case by using iteration - instead of recursion. - We have a relatively small recursion limit of about 10 operations. This - is a compilation limit (a define). It can be hit if many expr vars or - function calls are concatenated. The new optimization is very similar to - the existing one, which optimizes consecutive concatenations in node2 of - the tree. The new one optimizes consecutive concatenations in node 1. - trunk patch: http://svn.apache.org/r1657685 - 2.4.x patch: trunk works (modulo CHANGES) - +1: rjung, ylavic, covener - * Save a few bytes in conf pool when parsing some directives. Use temp_pool when applicable. trunk patch: http://svn.apache.org/r1657692 diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c index ebdbe2ae202..1038e7aeed9 100644 --- a/server/util_expr_eval.c +++ b/server/util_expr_eval.c @@ -96,7 +96,8 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx, node->node_arg2); break; case op_Concat: - if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat) { + if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat && + ((ap_expr_t *)node->node_arg1)->node_op != op_Concat) { const char *s1 = ap_expr_eval_word(ctx, node->node_arg1); const char *s2 = ap_expr_eval_word(ctx, node->node_arg2); if (!*s1) @@ -106,6 +107,30 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx, else result = apr_pstrcat(ctx->p, s1, s2, NULL); } + else if (((ap_expr_t *)node->node_arg1)->node_op == op_Concat) { + const ap_expr_t *nodep = node; + int n; + int i = 1; + struct iovec *vec; + do { + nodep = nodep->node_arg1; + i++; + } while (nodep->node_op == op_Concat); + vec = apr_palloc(ctx->p, i * sizeof(struct iovec)); + n = i; + nodep = node; + i--; + do { + vec[i].iov_base = (void *)ap_expr_eval_word(ctx, + nodep->node_arg2); + vec[i].iov_len = strlen(vec[i].iov_base); + i--; + nodep = nodep->node_arg1; + } while (nodep->node_op == op_Concat); + vec[i].iov_base = (void *)ap_expr_eval_word(ctx, nodep); + vec[i].iov_len = strlen(vec[i].iov_base); + result = apr_pstrcatv(ctx->p, vec, n, NULL); + } else { const ap_expr_t *nodep = node; int i = 1;