From f3ce9d0180d2fe29195ce846795c0579d4d20a5e Mon Sep 17 00:00:00 2001 From: Rainer Jung Date: Tue, 24 Feb 2015 18:25:26 +0000 Subject: [PATCH] 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 --- CHANGES | 3 +++ STATUS | 11 ----------- server/util_expr_eval.c | 27 ++++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index ef32d26384..54f0c3b991 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 c623baaa0a..05162f2978 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 ebdbe2ae20..1038e7aeed 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; -- 2.50.1