diff options
| author | Paul Eggert | 2019-03-27 21:03:10 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-03-27 21:24:26 -0700 |
| commit | 81795bb71394aac6d7f6f7fd2656b2eb79a39a4d (patch) | |
| tree | ff9f813ebc27ba20ebd502412826d782d223b0f6 /src | |
| parent | eac5f967ca700c5f47cf673cb4c06b07c4f42ac2 (diff) | |
| download | emacs-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.c | 26 | ||||
| -rw-r--r-- | src/regex-emacs.h | 2 |
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; |