diff --git a/grep-2.27-dfa-performance-fix.patch b/grep-2.27-dfa-performance-fix.patch new file mode 100644 index 0000000..d8d1345 --- /dev/null +++ b/grep-2.27-dfa-performance-fix.patch @@ -0,0 +1,73 @@ +diff --git a/lib/dfa.c b/lib/dfa.c +--- a/lib/dfa.c ++++ b/lib/dfa.c +@@ -2807,39 +2807,33 @@ realloc_trans_if_necessary (struct dfa *d, state_num new_state) + static state_num + build_state (state_num s, struct dfa *d, unsigned char uc) + { +- state_num *trans; /* The new transition table. */ +- state_num i, maxstate; ++ /* A pointer to the new transition table, and the table itself. */ ++ state_num **ptrans = (ACCEPTING (s, *d) ? d->fails : d->trans) + s; ++ state_num *trans = *ptrans; + +- if (d->fails[s] != NULL) +- trans = d->fails[s]; +- else ++ if (!trans) + { +- state_num **ptrans = (ACCEPTING (s, *d) ? d->fails : d->trans) + s; +- if (!*ptrans) ++ /* MAX_TRCOUNT is an arbitrary upper limit on the number of ++ transition tables that can exist at once, other than for ++ initial states. Often-used transition tables are quickly ++ rebuilt, whereas rarely-used ones are cleared away. */ ++ if (MAX_TRCOUNT <= d->trcount) + { +- /* MAX_TRCOUNT is an arbitrary upper limit on the number of +- transition tables that can exist at once, other than for +- initial states. Often-used transition tables are quickly +- rebuilt, whereas rarely-used ones are cleared away. */ +- if (MAX_TRCOUNT <= d->trcount) ++ for (state_num i = d->min_trcount; i < d->tralloc; i++) + { +- for (i = d->min_trcount; i < d->tralloc; i++) +- { +- free (d->trans[i]); +- free (d->fails[i]); +- d->trans[i] = d->fails[i] = NULL; +- } +- d->trcount = 0; ++ free (d->trans[i]); ++ free (d->fails[i]); ++ d->trans[i] = d->fails[i] = NULL; + } +- +- d->trcount++; +- *ptrans = xmalloc (NOTCHAR * sizeof *trans); ++ d->trcount = 0; + } +- trans = *ptrans; ++ ++ d->trcount++; ++ *ptrans = trans = xmalloc (NOTCHAR * sizeof *trans); + + /* Fill transition table with a default value which means that the + transited state has not been calculated yet. */ +- for (i = 0; i < NOTCHAR; i++) ++ for (int i = 0; i < NOTCHAR; i++) + trans[i] = -2; + } + +@@ -2857,8 +2851,8 @@ build_state (state_num s, struct dfa *d, unsigned char uc) + /* Now go through the new transition table, and make sure that the trans + and fail arrays are allocated large enough to hold a pointer for the + largest state mentioned in the table. */ +- maxstate = -1; +- for (i = 0; i < NOTCHAR; ++i) ++ state_num maxstate = -1; ++ for (int i = 0; i < NOTCHAR; i++) + if (maxstate < trans[i]) + maxstate = trans[i]; + realloc_trans_if_necessary (d, maxstate); + diff --git a/grep.spec b/grep.spec index 6397cee..41d271c 100644 --- a/grep.spec +++ b/grep.spec @@ -3,7 +3,7 @@ Summary: Pattern matching utilities Name: grep Version: 2.27 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ URL: http://www.gnu.org/software/grep/ Group: Applications/Text @@ -17,6 +17,8 @@ Source4: grepconf.sh Patch0: grep-2.27-man-fix-gs.patch # upstream ticket 39445 Patch1: grep-2.27-help-align.patch +# backported from gnulib (rhbz#1412800) +Patch2: grep-2.27-dfa-performance-fix.patch Requires(post): /sbin/install-info Requires(preun): /sbin/install-info @@ -36,6 +38,7 @@ GNU grep is needed by many scripts, so it shall be installed on every system. %setup -q %patch0 -p1 -b .man-fix-gs %patch1 -p1 -b .help-align +%patch2 -p1 -b .dfa-performance-fix %build %global BUILD_FLAGS $RPM_OPT_FLAGS @@ -86,6 +89,10 @@ fi %{_libexecdir}/grepconf.sh %changelog +* Mon Feb 20 2017 Jaroslav Škarvada - 2.27-2 +- Fixed DFA performance regression (by dfa-performance-fix patch) + Resolves: rhbz#1412800 + * Wed Dec 7 2016 Jaroslav Škarvada - 2.27-1 - New version Resolves: rhbz#1402379