aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-03-27 21:03:10 -0700
committerPaul Eggert2019-03-27 21:24:26 -0700
commit81795bb71394aac6d7f6f7fd2656b2eb79a39a4d (patch)
treeff9f813ebc27ba20ebd502412826d782d223b0f6 /src
parenteac5f967ca700c5f47cf673cb4c06b07c4f42ac2 (diff)
downloademacs-81795bb71394aac6d7f6f7fd2656b2eb79a39a4d.tar.gz
emacs-81795bb71394aac6d7f6f7fd2656b2eb79a39a4d.zip
Tweak re_registers allocation
* src/regex-emacs.c (re_match_2_internal): No need to allocate one extra trailing search register; Emacs does not use it. Avoid quadratic behavior on reallocation.
Diffstat (limited to 'src')
-rw-r--r--src/regex-emacs.c26
-rw-r--r--src/regex-emacs.h2
2 files changed, 10 insertions, 18 deletions
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 7629492bcf8..8dc69805024 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -3940,8 +3940,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
3940 } 3940 }
3941 3941
3942 /* Initialize subexpression text positions to -1 to mark ones that no 3942 /* Initialize subexpression text positions to -1 to mark ones that no
3943 start_memory/stop_memory has been seen for. Also initialize the 3943 start_memory/stop_memory has been seen for. */
3944 register information struct. */
3945 for (ptrdiff_t reg = 1; reg < num_regs; reg++) 3944 for (ptrdiff_t reg = 1; reg < num_regs; reg++)
3946 regstart[reg] = regend[reg] = NULL; 3945 regstart[reg] = regend[reg] = NULL;
3947 3946
@@ -4091,10 +4090,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4091 { 4090 {
4092 /* Have the register data arrays been allocated? */ 4091 /* Have the register data arrays been allocated? */
4093 if (bufp->regs_allocated == REGS_UNALLOCATED) 4092 if (bufp->regs_allocated == REGS_UNALLOCATED)
4094 { /* No. So allocate them with malloc. We need one 4093 { /* No. So allocate them with malloc. */
4095 extra element beyond 'num_regs' for the '-1' marker 4094 ptrdiff_t n = max (RE_NREGS, num_regs);
4096 GNU code uses. */
4097 ptrdiff_t n = max (RE_NREGS, num_regs + 1);
4098 regs->start = xnmalloc (n, sizeof *regs->start); 4095 regs->start = xnmalloc (n, sizeof *regs->start);
4099 regs->end = xnmalloc (n, sizeof *regs->end); 4096 regs->end = xnmalloc (n, sizeof *regs->end);
4100 regs->num_regs = n; 4097 regs->num_regs = n;
@@ -4104,9 +4101,10 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4104 { /* Yes. If we need more elements than were already 4101 { /* Yes. If we need more elements than were already
4105 allocated, reallocate them. If we need fewer, just 4102 allocated, reallocate them. If we need fewer, just
4106 leave it alone. */ 4103 leave it alone. */
4107 if (regs->num_regs < num_regs + 1) 4104 ptrdiff_t n = regs->num_regs;
4105 if (n < num_regs)
4108 { 4106 {
4109 ptrdiff_t n = num_regs + 1; 4107 n = max (n + (n >> 1), num_regs);
4110 regs->start 4108 regs->start
4111 = xnrealloc (regs->start, n, sizeof *regs->start); 4109 = xnrealloc (regs->start, n, sizeof *regs->start);
4112 regs->end = xnrealloc (regs->end, n, sizeof *regs->end); 4110 regs->end = xnrealloc (regs->end, n, sizeof *regs->end);
@@ -4137,10 +4135,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4137 } 4135 }
4138 4136
4139 /* If the regs structure we return has more elements than 4137 /* If the regs structure we return has more elements than
4140 were in the pattern, set the extra elements to -1. If 4138 were in the pattern, set the extra elements to -1. */
4141 we (re)allocated the registers, this is the case,
4142 because we always allocate enough to have at least one
4143 -1 at the end. */
4144 for (ptrdiff_t reg = num_regs; reg < regs->num_regs; reg++) 4139 for (ptrdiff_t reg = num_regs; reg < regs->num_regs; reg++)
4145 regs->start[reg] = regs->end[reg] = -1; 4140 regs->start[reg] = regs->end[reg] = -1;
4146 } 4141 }
@@ -5053,13 +5048,10 @@ re_compile_pattern (const char *pattern, ptrdiff_t length,
5053 bool posix_backtracking, const char *whitespace_regexp, 5048 bool posix_backtracking, const char *whitespace_regexp,
5054 struct re_pattern_buffer *bufp) 5049 struct re_pattern_buffer *bufp)
5055{ 5050{
5056 reg_errcode_t ret;
5057
5058 /* GNU code is written to assume at least RE_NREGS registers will be set
5059 (and at least one extra will be -1). */
5060 bufp->regs_allocated = REGS_UNALLOCATED; 5051 bufp->regs_allocated = REGS_UNALLOCATED;
5061 5052
5062 ret = regex_compile ((re_char *) pattern, length, 5053 reg_errcode_t ret
5054 = regex_compile ((re_char *) pattern, length,
5063 posix_backtracking, 5055 posix_backtracking,
5064 whitespace_regexp, 5056 whitespace_regexp,
5065 bufp); 5057 bufp);
diff --git a/src/regex-emacs.h b/src/regex-emacs.h
index 95f743dc2fb..ddf14e0d9e1 100644
--- a/src/regex-emacs.h
+++ b/src/regex-emacs.h
@@ -98,7 +98,7 @@ struct re_pattern_buffer
98 bool_bf can_be_null : 1; 98 bool_bf can_be_null : 1;
99 99
100 /* If REGS_UNALLOCATED, allocate space in the 'regs' structure 100 /* If REGS_UNALLOCATED, allocate space in the 'regs' structure
101 for 'max (RE_NREGS, re_nsub + 1)' groups. 101 for at least (re_nsub + 1) groups.
102 If REGS_REALLOCATE, reallocate space if necessary. 102 If REGS_REALLOCATE, reallocate space if necessary.
103 If REGS_FIXED, use what's there. */ 103 If REGS_FIXED, use what's there. */
104 unsigned regs_allocated : 2; 104 unsigned regs_allocated : 2;