Hi Willy, fair points.

Kind regards.

On 21 July 2017 at 08:10, Willy Tarreau <[email protected]> wrote:

> Hi Aleks,
>
> On Fri, Jul 21, 2017 at 09:03:27AM +0200, Aleksandar Lazic wrote:
> > I thought something like
> >
> > `my_pcrealloc` use `create_pool` inside and `my_pcrefree` use
> > `pool_destroy2` but one of the main question is how does the pcre2
> > handle the custom memory struct we have in the pools.
> >
> > http://git.haproxy.org/?p=haproxy.git;a=blob;f=src/memory.c;hb=HEAD#l40
> > http://git.haproxy.org/?p=haproxy.git;a=blob;f=src/memory.c;hb=HEAD#l198
>
> There wouldn't be any benefit in doing this because our pools are fixed
> size and are not compatible with a malloc() call by definition. Also,
> pcre will call malloc() while compiling the regex, which is normally
> not done at run time so there's no benefit in trying to optimize for
> performance during this stage. However I agree that instrumenting a
> malloc() call is sometimes quite useful.
>
> Willy
>
From a5bcdc300651d4bca888ba151a6055a3760a5e27 Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Fri, 21 Jul 2017 07:26:38 +0100
Subject: [PATCH] MINOR: regex: using allocators macros

Only pools use it at the moment, but since pcre
(via its global pcre_malloc/pcre_free) and pcre2
(via contexts) can override memory management functions
as well, we use here this possibility.
---
 include/common/regex.h |  6 ++++--
 src/regex.c            | 37 ++++++++++++++++++++++++++++++++++---
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/include/common/regex.h b/include/common/regex.h
index 2f171b3b..ec906a23 100644
--- a/include/common/regex.h
+++ b/include/common/regex.h
@@ -55,6 +55,7 @@ struct my_regex {
 #endif
 #elif USE_PCRE2
 	pcre2_code *reg;
+	pcre2_general_context *ctx;
 #else /* no PCRE */
 	regex_t regex;
 #endif
@@ -105,7 +106,7 @@ static inline int regex_exec(const struct my_regex *preg, char *subject) {
 	pcre2_match_data *pm;
 	int ret;
 
-	pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
+	pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx);
 	ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject),
 		0, 0, pm, NULL);
 	pcre2_match_data_free(pm);
@@ -136,7 +137,7 @@ static inline int regex_exec2(const struct my_regex *preg, char *subject, int le
 	pcre2_match_data *pm;
 	int ret;
 
-	pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
+	pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx);
 	ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length,
 		0, 0, pm, NULL);
 	pcre2_match_data_free(pm);
@@ -172,6 +173,7 @@ static inline void regex_free(struct my_regex *preg) {
 	pcre_free(preg->extra);
 #endif /* PCRE_CONFIG_JIT */
 #elif defined(USE_PCRE2) || defined(USE_PCRE2_JIT)
+	pcre2_general_context_free(preg->ctx);
 	pcre2_code_free(preg->reg);
 #else
 	regfree(&preg->regex);
diff --git a/src/regex.c b/src/regex.c
index 38d7132b..f2d30a9a 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -19,6 +19,7 @@
 #include <common/defaults.h>
 #include <common/regex.h>
 #include <common/standard.h>
+#include <common/memory.h>
 #include <proto/log.h>
 
 /* regex trash buffer used by various regex tests */
@@ -197,7 +198,7 @@ int regex_exec_match(const struct my_regex *preg, const char *subject,
 	 * space in the matches array.
 	 */
 #ifdef USE_PCRE2
-	pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
+	pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx);
 	ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, options, pm, NULL);
 
 	if (ret < 0) {
@@ -208,7 +209,6 @@ int regex_exec_match(const struct my_regex *preg, const char *subject,
 	matches = pcre2_get_ovector_pointer(pm);
 #else
 	ret = pcre_exec(preg->reg, preg->extra, subject, strlen(subject), 0, options, matches, enmatch * 3);
-
 	if (ret < 0)
 		return 0;
 #endif
@@ -290,7 +290,7 @@ int regex_exec_match2(const struct my_regex *preg, char *subject, int length,
 	 * space in the matches array.
 	 */
 #ifdef USE_PCRE2
-	pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
+	pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx);
 	ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length, 0, options, pm, NULL);
 
 	if (ret < 0) {
@@ -337,6 +337,34 @@ int regex_exec_match2(const struct my_regex *preg, char *subject, int length,
 #endif
 }
 
+#if defined(USE_PCRE) || defined(USE_PCRE_JIT)
+static void *
+my_pcrealloc(size_t size)
+{
+	return MALLOC(size);
+}
+
+static void
+my_pcrefree(void *ptr)
+{
+	FREE(ptr);
+}
+#elif defined(USE_PCRE2) || defined(USE_PCRE2_JIT)
+static void *
+my_pcrealloc(PCRE2_SIZE size, void *a)
+{
+	(void)a;
+	return MALLOC(size);
+}
+
+static void
+my_pcrefree(void *ptr, void *a)
+{
+	(void)a;
+	FREE(ptr);
+}
+#endif
+
 int regex_comp(const char *str, struct my_regex *regex, int cs, int cap, char **err)
 {
 #if defined(USE_PCRE) || defined(USE_PCRE_JIT)
@@ -375,6 +403,7 @@ int regex_comp(const char *str, struct my_regex *regex, int cs, int cap, char **
 	if (!cap)
 		flags |= PCRE2_NO_AUTO_CAPTURE;
 
+	regex->ctx = pcre2_general_context_create(my_pcrealloc, my_pcrefree, NULL);
 	regex->reg = pcre2_compile((PCRE2_SPTR)str, PCRE2_ZERO_TERMINATED, flags, &errn, &erroffset, NULL);
 	if (!regex->reg) {
 		pcre2_get_error_message(errn, error, sizeof(error));
@@ -417,6 +446,8 @@ static void __regex_init(void)
 	char *ptr = NULL;
 
 #ifdef USE_PCRE
+	pcre_malloc = my_pcrealloc;
+	pcre_free = my_pcrefree;
 	memprintf(&ptr, "Built with PCRE version : %s", (HAP_XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
 		HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
 		HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR) HAP_XSTRING(PCRE_PRERELEASE PCRE_DATE));
-- 
2.13.3

Reply via email to