diff --git a/grep.c b/grep.c index cd952ef5d3cca5..d6d29fc7243c6d 100644 --- a/grep.c +++ b/grep.c @@ -482,13 +482,33 @@ static void free_pcre1_regexp(struct grep_pat *p) #endif /* !USE_LIBPCRE1 */ #ifdef USE_LIBPCRE2 +static void *pcre2_malloc(PCRE2_SIZE size, void *memory_data) +{ + return malloc(size); +} + +static void pcre2_free(void *pointer, void *memory_data) +{ + return free(pointer); +} + +static pcre2_general_context *get_pcre2_context(void) +{ + static pcre2_general_context *context; + + if (!context) + context = pcre2_general_context_create(pcre2_malloc, + pcre2_free, NULL); + + return context; +} + static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) { int error; PCRE2_UCHAR errbuf[256]; PCRE2_SIZE erroffset; int options = PCRE2_MULTILINE; - const uint8_t *character_tables = NULL; int jitret; int patinforet; size_t jitsizearg; @@ -499,9 +519,11 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt if (opt->ignore_case) { if (has_non_ascii(p->pattern)) { - character_tables = pcre2_maketables(NULL); - p->pcre2_compile_context = pcre2_compile_context_create(NULL); - pcre2_set_character_tables(p->pcre2_compile_context, character_tables); + p->pcre2_tables = pcre2_maketables(get_pcre2_context()); + p->pcre2_compile_context = + pcre2_compile_context_create(get_pcre2_context()); + pcre2_set_character_tables(p->pcre2_compile_context, + p->pcre2_tables); } options |= PCRE2_CASELESS; } @@ -513,7 +535,8 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt p->pcre2_compile_context); if (p->pcre2_pattern) { - p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, NULL); + p->pcre2_match_data = + pcre2_match_data_create_from_pattern(p->pcre2_pattern, get_pcre2_context()); if (!p->pcre2_match_data) die("Couldn't allocate PCRE2 match data"); } else { @@ -550,7 +573,7 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt return; } - p->pcre2_jit_stack = pcre2_jit_stack_create(1, 1024 * 1024, NULL); + p->pcre2_jit_stack = pcre2_jit_stack_create(1, 1024 * 1024, get_pcre2_context()); if (!p->pcre2_jit_stack) die("Couldn't allocate PCRE2 JIT stack"); p->pcre2_match_context = pcre2_match_context_create(NULL); @@ -605,6 +628,7 @@ static void free_pcre2_pattern(struct grep_pat *p) pcre2_match_data_free(p->pcre2_match_data); pcre2_jit_stack_free(p->pcre2_jit_stack); pcre2_match_context_free(p->pcre2_match_context); + free((void *)p->pcre2_tables); } #else /* !USE_LIBPCRE2 */ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) diff --git a/grep.h b/grep.h index 1875880f37990f..26d21a3433eb2c 100644 --- a/grep.h +++ b/grep.h @@ -96,6 +96,7 @@ struct grep_pat { pcre2_compile_context *pcre2_compile_context; pcre2_match_context *pcre2_match_context; pcre2_jit_stack *pcre2_jit_stack; + const uint8_t *pcre2_tables; uint32_t pcre2_jit_on; kwset_t kws; unsigned fixed:1;