On Sun, Jan 19, 2014 at 9:57 PM, Bram Moolenaar <[email protected]> wrote:
> > Christian Brabandt wrote: > > > On Mi, 15 Jan 2014, Aidan Marlin wrote: > > > Vim devs, > > > > > > I have discovered a bug which affects at least 7.4.135 and (likely) > 7.3.547. Example file is available at > https://mega.co.nz/#!ndVjXZTY!aMX_9ll-0ce861tQwNZBaFveb_kONCJxvAT2GZOvzlc(1.2MB > in size) which will crash vim when attempting the following regex: > > > > > > :%s/\n//g > > > > > > The file contains 20 000 lines, each line containing 60 characters. > > > > > > Join (:%j) works fine and fast in these versions of vim, while the > above regex seems to consume excessive amounts of memory, and results in > vim crash. > > > > How about to alias :s/\n// to the join function (see attached patch). > > OK, but with a slightly different pattern it would still be a problem. > Did you look at the cause of the problem? ":%s/\n//" process lines one by one. 1) a <save for undo b c 2) ab <replace b c 3) ab b <save for undo c 4) ab c <delete 5) ab <save for undo c 6) abc <replace c 7) abc c <save for undo 8) abc <delete So, undo memory size is about m * (((n + 1) * n / 2) - 1), where n is number of lines and m is line length. Perhaps it might be possible to re-use undo entry even after insert or delete lines when new change is done above it? diff -r 89b3a7ef9622 src/undo.c --- a/src/undo.c Thu Jan 23 22:45:58 2014 +0100 +++ b/src/undo.c Sun Jan 26 20:52:22 2014 +0900 @@ -565,16 +565,18 @@ break; /* If lines have been inserted/deleted we give up. - * Also when the line was included in a multi-line save. */ - if ((curbuf->b_u_newhead->uh_getbot_entry != uep + * Also when the line was included in a multi-line save. + * Except when new change is done above this entry. */ + if (bot > uep->ue_top + 1 + && ((curbuf->b_u_newhead->uh_getbot_entry != uep ? (uep->ue_top + uep->ue_size + 1 != (uep->ue_bot == 0 ? curbuf->b_ml.ml_line_count + 1 : uep->ue_bot)) : uep->ue_lcount != curbuf->b_ml.ml_line_count) - || (uep->ue_size > 1 - && top >= uep->ue_top - && top + 2 <= uep->ue_top + uep->ue_size + 1)) + || (uep->ue_size > 1 + && top >= uep->ue_top + && top + 2 <= uep->ue_top + uep->ue_size + 1))) break; /* If it's the same line we can skip saving it again. */ -- Yukihiro Nakadaira - [email protected] -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
