From d35af63cd671563fd188c3b0a1ef30067027c7aa Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 22 Jun 2012 14:17:42 -0700 Subject: Support higher-resolution time stamps. Fixes: debbugs:9000 --- src/buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index e501c9b73cc..89a4e26fb73 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -709,7 +709,7 @@ reset_buffer (register struct buffer *b) BVAR (b, filename) = Qnil; BVAR (b, file_truename) = Qnil; BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil; - b->modtime = 0; + EMACS_SET_SECS_NSECS (b->modtime, 0, UNKNOWN_MODTIME_NSECS); b->modtime_size = -1; XSETFASTINT (BVAR (b, save_length), 0); b->last_window_start = 1; @@ -5834,9 +5834,9 @@ An entry (TEXT . POSITION) represents the deletion of the string TEXT from (abs POSITION). If POSITION is positive, point was at the front of the text being deleted; if negative, point was at the end. -An entry (t HIGH . LOW) indicates that the buffer previously had -\"unmodified\" status. HIGH and LOW are the high and low 16-bit portions -of the visited file's modification time, as of that time. If the +An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously +unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time) +and is the visited file's modification time, as of that time. If the modification time of the most recent save is different, this entry is obsolete. -- cgit v1.2.1 From 36429c89cbd7282a7614a358e5edb4d37f4a3f47 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 3 Jul 2012 07:57:52 +0400 Subject: Cleanup basic buffer management. * buffer.h (struct buffer): Change layout to use generic vector marking code. Fix some comments. Change type of 'clip_changed' to bitfield. Remove unused #ifndef old. (FIRST_FIELD_PER_BUFFER, LAST_FIELD_PER_BUFFER): Remove. (GET_OVERLAYS_AT): Fix indentation. (for_each_per_buffer_object_at): New macro. * buffer.c (clone_per_buffer_values, reset_buffer_local_variables) (Fbuffer_local_variables): Use it. (init_buffer_once, syms_of_buffer): Remove unused #ifndef old. * alloc.c (allocate_buffer): Adjust to match new layout of struct buffer. Fix comment. (mark_overlay): New function. (mark_buffer): Use it. Use mark_vectorlike to mark normal Lisp area of struct buffer. (mark_object): Use it. Adjust marking of misc objects and related comments. --- src/buffer.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 89a4e26fb73..08118baa3d7 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -465,11 +465,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) XSETBUFFER (to_buffer, to); - /* buffer-local Lisp variables start at `undo_list', - tho only the ones from `name' on are GC'd normally. */ - for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER); - offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER); - offset += sizeof (Lisp_Object)) + for_each_per_buffer_object_at (offset) { Lisp_Object obj; @@ -820,14 +816,8 @@ reset_buffer_local_variables (register struct buffer *b, int permanent_too) if (permanent_too || buffer_permanent_local_flags[i] == 0) SET_PER_BUFFER_VALUE_P (b, i, 0); - /* For each slot that has a default value, - copy that into the slot. */ - - /* buffer-local Lisp variables start at `undo_list', - tho only the ones from `name' on are GC'd normally. */ - for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER); - offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER); - offset += sizeof (Lisp_Object)) + /* For each slot that has a default value, copy that into the slot. */ + for_each_per_buffer_object_at (offset) { int idx = PER_BUFFER_IDX (offset); if ((idx > 0 @@ -1063,12 +1053,7 @@ No argument or nil as argument means use current buffer as BUFFER. */) { int offset, idx; - /* buffer-local Lisp variables start at `undo_list', - tho only the ones from `name' on are GC'd normally. */ - for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER); - offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER); - /* sizeof EMACS_INT == sizeof Lisp_Object */ - offset += (sizeof (EMACS_INT))) + for_each_per_buffer_object_at (offset) { idx = PER_BUFFER_IDX (offset); if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) @@ -4903,9 +4888,7 @@ init_buffer_once (void) BVAR (&buffer_defaults, case_fold_search) = Qt; BVAR (&buffer_defaults, auto_fill_function) = Qnil; BVAR (&buffer_defaults, selective_display) = Qnil; -#ifndef old BVAR (&buffer_defaults, selective_display_ellipses) = Qt; -#endif BVAR (&buffer_defaults, abbrev_table) = Qnil; BVAR (&buffer_defaults, display_table) = Qnil; BVAR (&buffer_defaults, undo_list) = Qnil; @@ -4984,9 +4967,7 @@ init_buffer_once (void) XSETFASTINT (BVAR (&buffer_local_flags, case_fold_search), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, auto_fill_function), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx; -#ifndef old XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx; -#endif XSETFASTINT (BVAR (&buffer_local_flags, tab_width), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, truncate_lines), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx; @@ -5594,12 +5575,10 @@ A value of t means that the character ^M makes itself and all the rest of the line invisible; also, when saving the buffer in a file, save the ^M as a newline. */); -#ifndef old DEFVAR_PER_BUFFER ("selective-display-ellipses", &BVAR (current_buffer, selective_display_ellipses), Qnil, doc: /* Non-nil means display ... on previous line when a line is invisible. */); -#endif DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode), Qnil, doc: /* Non-nil if self-insertion should replace existing text. -- cgit v1.2.1 From 8e4fd1e172f5fc3daf8219965a588bf0125ba311 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 3 Jul 2012 13:47:32 -0400 Subject: Speed up generate-new-buffer-name for invisible buffers (bug#1229) * src/buffer.c (Fgenerate_new_buffer_name): Speed up finding a new buffer for invisible buffers. * src/lisp.h (Frandom): Make it visible to C. --- src/buffer.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 08118baa3d7..83f0eb153c5 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -838,10 +838,14 @@ If there is no live buffer named NAME, then return NAME. Otherwise modify name by appending `', incrementing NUMBER \(starting at 2) until an unused name is found, and then return that name. Optional second argument IGNORE specifies a name that is okay to use (if -it is in the sequence to be tried) even if a buffer with that name exists. */) +it is in the sequence to be tried) even if a buffer with that name exists. + +If NAME begins with a space (i.e., a buffer that is not normally +visible to users), then if buffer NAME already exists a random number +is first appended to NAME, to speed up finding a non-existent buffer. */) (register Lisp_Object name, Lisp_Object ignore) { - register Lisp_Object gentemp, tem; + register Lisp_Object gentemp, tem, tem2; ptrdiff_t count; char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"]; @@ -854,11 +858,23 @@ it is in the sequence to be tried) even if a buffer with that name exists. */) if (NILP (tem)) return name; + if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */ + { + /* Note fileio.c:make_temp_name does random differently. */ + sprintf (number, "-%"pD"d", Frandom (make_number (999999))); + tem2 = concat2 (name, build_string (number)); + tem = Fget_buffer (tem2); + if (NILP (tem)) + return tem2; + } + else + tem2 = name; + count = 1; while (1) { sprintf (number, "<%"pD"d>", ++count); - gentemp = concat2 (name, build_string (number)); + gentemp = concat2 (tem2, build_string (number)); tem = Fstring_equal (gentemp, ignore); if (!NILP (tem)) return gentemp; -- cgit v1.2.1 From 404dbd373a91c0b994005e88fe703d9144873b27 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 3 Jul 2012 12:24:42 -0600 Subject: Auto-generate EXFUN using make-docfile src * window.c (Fset_window_margins, Fset_window_fringes) (Fset_window_scroll_bars, Fset_window_vscroll): No longer static. * textprop.c (Fprevious_property_change): No longer static. * syntax.c (Fsyntax_table_p): No longer static. * process.c (Fget_process, Fprocess_datagram_address): No longer static. * keymap.c (Flookup_key, Fcopy_keymap): No longer static. * keyboard.c (Fcommand_execute): No longer static. Remove EXFUN. * insdel.c (Fcombine_after_change_execute): No longer static. * image.c (Finit_image_library): No longer static. * fileio.c (Fmake_symbolic_link): No longer static. * eval.c (Ffetch_bytecode): No longer static. * editfns.c (Fuser_full_name): No longer static. * doc.c: (Fdocumentation_property, Fsnarf_documentation): No longer static. * buffer.c (Fset_buffer_major_mode, Fdelete_overlay): No longer static. * dired.c (Ffile_attributes): No longer static. * composite.c (Fcomposition_get_gstring): No longer static. * callproc.c (Fgetenv_internal): No longer static. * ccl.h: Remove EXFUNs. * buffer.h: Remove EXFUNs. * dispextern.h: Remove EXFUNs. * intervals.h: Remove EXFUNs. * fontset.h: Remove EXFUN. * font.h: Remove EXFUNs. * dosfns.c (system_process_attributes): Remove EXFUN. * keymap.h: Remove EXFUNs. * lisp.h: Remove EXFUNs. * w32term.h: Remove EXFUNs. * window.h: Remove EXFUNs. * xsettings.h: Remove EXFUN. * xterm.h: Remove EXFUN. lib-src * make-docfile.c (enum global_type) : New constant. (struct global) : New field. (add_global): Add 'value' argument. (compare_globals): Sort functions at the end. (close_emacs_globals): New function. (write_globals): Handle functions. (scan_c_file): Call add_global for DEFUN. --- src/buffer.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 83f0eb153c5..2f8705c9a32 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -107,8 +107,6 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; int last_per_buffer_idx; -static Lisp_Object Fset_buffer_major_mode (Lisp_Object); -static Lisp_Object Fdelete_overlay (Lisp_Object); static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, int after, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3); -- cgit v1.2.1 From 76046526fe2d8c098b04697a5c3910adb8a84aca Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 4 Jul 2012 07:49:19 +0400 Subject: * buffer.c (Fgenerate_new_buffer_name): Fix type mismatch. --- src/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 2f8705c9a32..d9c0796af33 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -859,7 +859,7 @@ is first appended to NAME, to speed up finding a non-existent buffer. */) if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */ { /* Note fileio.c:make_temp_name does random differently. */ - sprintf (number, "-%"pD"d", Frandom (make_number (999999))); + sprintf (number, "-%"pD"d", XFASTINT (Frandom (make_number (999999)))); tem2 = concat2 (name, build_string (number)); tem = Fget_buffer (tem2); if (NILP (tem)) -- cgit v1.2.1 From dea7f1e5a400cfa9a42eef08be86cdc0992660b5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 Jul 2012 22:39:36 -0700 Subject: * buffer.c (Fgenerate_new_buffer_name): Fix sprintf format mismatch. --- src/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index d9c0796af33..1e68d7d6b74 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -859,7 +859,7 @@ is first appended to NAME, to speed up finding a non-existent buffer. */) if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */ { /* Note fileio.c:make_temp_name does random differently. */ - sprintf (number, "-%"pD"d", XFASTINT (Frandom (make_number (999999)))); + sprintf (number, "-%"pI"d", XFASTINT (Frandom (make_number (999999)))); tem2 = concat2 (name, build_string (number)); tem = Fget_buffer (tem2); if (NILP (tem)) -- cgit v1.2.1 From 3884d954f32acb816332d7837fe813bc546f6268 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 4 Jul 2012 19:49:46 +0400 Subject: * buffer.c (init_buffer_once): Fix initialization of headers for buffer_defaults and buffer_local_symbols. Reported by Juanma Barranquero . --- src/buffer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 1e68d7d6b74..e1652e9e105 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4870,6 +4870,12 @@ void init_buffer_once (void) { int idx; + /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make + sure that this is still correct. Otherwise, mark_vectorlike may not + trace all Lisp_Objects in buffer_defaults and buffer_local_symbols. */ + const int pvecsize + = (offsetof (struct buffer, own_text) - sizeof (struct vectorlike_header)) + / sizeof (Lisp_Object); memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags); @@ -4886,9 +4892,9 @@ init_buffer_once (void) buffer_local_symbols.text = &buffer_local_symbols.own_text; BUF_INTERVALS (&buffer_defaults) = 0; BUF_INTERVALS (&buffer_local_symbols) = 0; - XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, 0); + XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize); XSETBUFFER (Vbuffer_defaults, &buffer_defaults); - XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, 0); + XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize); XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols); /* Set up the default values of various buffer slots. */ -- cgit v1.2.1 From 23f86fce48e1cc8118f0ea5cce49d1acfd4364c4 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 5 Jul 2012 10:32:41 +0400 Subject: Cleanup xmalloc. * admin/coccinelle/xzalloc.cocci: Semantic patch to convert calls to xmalloc with following memset to xzalloc. * src/lisp.h (xzalloc): New prototype. Omit needless casts. * src/alloc.c (xzalloc): New function. Omit needless casts. * src/charset.c: Omit needless casts. Convert all calls to malloc with following memset to xzalloc. * src/dispnew.c: Likewise. * src/fringe.c: Likewise. * src/image.c: Likewise. * src/sound.c: Likewise. * src/term.c: Likewise. * src/w32fns.c: Likewise. * src/w32font.c: Likewise. * src/w32term.c: Likewise. * src/xfaces.c: Likewise. * src/xfns.c: Likewise. * src/xterm.c: Likewise. * src/atimer.c: Omit needless casts. * src/buffer.c: Likewise. * src/callproc.c: Likewise. * src/ccl.c: Likewise. * src/coding.c: Likewise. * src/composite.c: Likewise. * src/doc.c: Likewise. * src/doprnt.c: Likewise. * src/editfns.c: Likewise. * src/emacs.c: Likewise. * src/eval.c: Likewise. * src/filelock.c: Likewise. * src/fns.c: Likewise. * src/gtkutil.c: Likewise. * src/keyboard.c: Likewise. * src/lisp.h: Likewise. * src/lread.c: Likewise. * src/minibuf.c: Likewise. * src/msdos.c: Likewise. * src/print.c: Likewise. * src/process.c: Likewise. * src/region-cache.c: Likewise. * src/search.c: Likewise. * src/sysdep.c: Likewise. * src/termcap.c: Likewise. * src/terminal.c: Likewise. * src/tparam.c: Likewise. * src/w16select.c: Likewise. * src/w32.c: Likewise. * src/w32reg.c: Likewise. * src/w32select.c: Likewise. * src/w32uniscribe.c: Likewise. * src/widget.c: Likewise. * src/xdisp.c: Likewise. * src/xmenu.c: Likewise. * src/xrdb.c: Likewise. * src/xselect.c: Likewise. --- src/buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index e1652e9e105..e1c33f4c711 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3893,7 +3893,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0, len = 10; /* We can't use alloca here because overlays_at can call xrealloc. */ - overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof (Lisp_Object)); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. */ @@ -3924,7 +3924,7 @@ end of the buffer. */) CHECK_NUMBER_COERCE_MARKER (end); len = 10; - overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof (Lisp_Object)); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. */ @@ -3952,7 +3952,7 @@ the value is (point-max). */) CHECK_NUMBER_COERCE_MARKER (pos); len = 10; - overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof (Lisp_Object)); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. @@ -3996,7 +3996,7 @@ the value is (point-min). */) return pos; len = 10; - overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof (Lisp_Object)); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. -- cgit v1.2.1 From 38182d901d030c7d65f4aa7a49b583afb30eb9b7 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 5 Jul 2012 11:35:48 -0700 Subject: More xmalloc and related cleanup. * alloc.c, bidi.c, buffer.c, buffer.h, bytecode.c, callint.c: * callproc.c, charset.c, coding.c, composite.c, data.c, dispnew.c: * doc.c, editfns.c, emacs.c, eval.c, fileio.c, filelock.c, fns.c: * font.c, fontset.c, frame.c, fringe.c, ftfont.c, ftxfont.c, gmalloc.c: * gtkutil.c, image.c, keyboard.c, keymap.c, lread.c, macros.c, menu.c: * nsfns.m, nsfont.m, nsmenu.m, nsterm.m, print.c, process.c, ralloc.c: * regex.c, region-cache.c, scroll.c, search.c, sound.c, syntax.c: * sysdep.c, term.c, termcap.c, unexmacosx.c, window.c, xdisp.c: * xfaces.c, xfns.c, xftfont.c, xgselect.c, xmenu.c, xrdb.c, xselect.c: * xterm.c: Omit needless casts involving void * pointers and allocation. Prefer "P = xmalloc (sizeof *P)" to "P = xmalloc (sizeof (TYPE_OF_P))", as the former is more robust if P's type is changed. Prefer xzalloc to xmalloc + memset 0. Simplify malloc-or-realloc to realloc. Don't worry about xmalloc returning a null pointer. Prefer xstrdup to xmalloc + strcpy. * editfns.c (Fmessage_box): Grow message_text by at least 80 when growing it. * keyboard.c (apply_modifiers_uncached): Prefer local array to alloca of a constant. --- src/buffer.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index e1c33f4c711..838932db4df 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2793,11 +2793,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay) Lisp_Object *v, tem; size = 10; - v = (Lisp_Object *) alloca (size * sizeof *v); + v = alloca (size * sizeof *v); n = overlays_in (start, end, 0, &v, &size, NULL, NULL); if (n > size) { - v = (Lisp_Object *) alloca (n * sizeof *v); + v = alloca (n * sizeof *v); overlays_in (start, end, 0, &v, &n, NULL, NULL); } @@ -2885,8 +2885,7 @@ ptrdiff_t sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) { ptrdiff_t i, j; - struct sortvec *sortvec; - sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec)); + struct sortvec *sortvec = alloca (noverlays * sizeof *sortvec); /* Put the valid and relevant overlays into sortvec. */ @@ -3893,7 +3892,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0, len = 10; /* We can't use alloca here because overlays_at can call xrealloc. */ - overlay_vec = xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof *overlay_vec); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. */ @@ -3924,7 +3923,7 @@ end of the buffer. */) CHECK_NUMBER_COERCE_MARKER (end); len = 10; - overlay_vec = xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof *overlay_vec); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. */ @@ -3952,7 +3951,7 @@ the value is (point-max). */) CHECK_NUMBER_COERCE_MARKER (pos); len = 10; - overlay_vec = xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof *overlay_vec); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. @@ -3996,7 +3995,7 @@ the value is (point-min). */) return pos; len = 10; - overlay_vec = xmalloc (len * sizeof (Lisp_Object)); + overlay_vec = xmalloc (len * sizeof *overlay_vec); /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. @@ -4251,7 +4250,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, int after, First copy the vector contents, in case some of these hooks do subsequent modification of the buffer. */ ptrdiff_t size = last_overlay_modification_hooks_used; - Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object)); + Lisp_Object *copy = alloca (size * sizeof *copy); ptrdiff_t i; memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents, @@ -4873,7 +4872,7 @@ init_buffer_once (void) /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make sure that this is still correct. Otherwise, mark_vectorlike may not trace all Lisp_Objects in buffer_defaults and buffer_local_symbols. */ - const int pvecsize + const int pvecsize = (offsetof (struct buffer, own_text) - sizeof (struct vectorlike_header)) / sizeof (Lisp_Object); @@ -5089,7 +5088,7 @@ init_buffer (void) if (!(IS_DIRECTORY_SEP (pwd[len - 1]))) { /* Grow buffer to add directory separator and '\0'. */ - pwd = (char *) realloc (pwd, len + 2); + pwd = realloc (pwd, len + 2); if (!pwd) fatal ("`get_current_dir_name' failed: %s\n", strerror (errno)); pwd[len] = DIRECTORY_SEP; -- cgit v1.2.1 From 041a49a645d9bbe7f249083d9065076bc8ccaa45 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 6 Jul 2012 08:42:30 +0400 Subject: Do not use Fdelete_overlay in delete_all_overlays to avoid redundant calls to unchain_overlay. * buffer.c (drop_overlay): New function. (delete_all_overlays, Fdelete_overlay): Use it. * minibuf.c (get_minibuffer): Fix comment. --- src/buffer.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 838932db4df..f73d2d07537 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -667,27 +667,40 @@ CLONE nil means the indirect buffer's state is reset to default values. */) return buf; } +/* Mark OV as no longer associated with B. */ + +static void +drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) +{ + eassert (b == XBUFFER (Fmarker_buffer (ov->start))); + modify_overlay (b, marker_position (ov->start), marker_position (ov->end)); + Fset_marker (ov->start, Qnil, Qnil); + Fset_marker (ov->end, Qnil, Qnil); + +} + +/* Delete all overlays of B and reset it's overlay lists. */ + void delete_all_overlays (struct buffer *b) { - Lisp_Object overlay; + struct Lisp_Overlay *ov, *next; - /* `reset_buffer' blindly sets the list of overlays to NULL, so we - have to empty the list, otherwise we end up with overlays that - think they belong to this buffer while the buffer doesn't know about - them any more. */ - while (b->overlays_before) + for (ov = b->overlays_before; ov; ov = next) { - XSETMISC (overlay, b->overlays_before); - Fdelete_overlay (overlay); + drop_overlay (b, ov); + next = ov->next; + ov->next = NULL; } - while (b->overlays_after) + + for (ov = b->overlays_after; ov; ov = next) { - XSETMISC (overlay, b->overlays_after); - Fdelete_overlay (overlay); + drop_overlay (b, ov); + next = ov->next; + ov->next = NULL; } - eassert (b->overlays_before == NULL); - eassert (b->overlays_after == NULL); + + b->overlays_before = b->overlays_after = NULL; } /* Reinitialize everything about a buffer except its name and contents @@ -3820,11 +3833,7 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0, = unchain_overlay (b->overlays_after, XOVERLAY (overlay)); eassert (XOVERLAY (overlay)->next == NULL); - modify_overlay (b, - marker_position (OVERLAY_START (overlay)), - marker_position (OVERLAY_END (overlay))); - Fset_marker (OVERLAY_START (overlay), Qnil, Qnil); - Fset_marker (OVERLAY_END (overlay), Qnil, Qnil); + drop_overlay (b, XOVERLAY (overlay)); /* When deleting an overlay with before or after strings, turn off display optimizations for the affected buffer, on the basis that -- cgit v1.2.1 From 657924ff58fc22a6e57dc8366a20dadf97324c63 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 6 Jul 2012 09:07:44 +0400 Subject: Introduce fast path for the widely used marker operation. * alloc.c (build_marker): New function. * lisp.h (build_marker): New prototype. * buffer.c (clone_per_buffer_values, Fmake_indirect_buffer): Use it. * composite.c (autocmp_chars): Likewise. * editfns.c (buildmark): Remove. (Fpoint_marker, Fpoint_min_marker, Fpoint_max_marker) (save_restriction_save): Use build_marker. * marker.c (buf_charpos_to_bytepos, buf_bytepos_to_charpos): Likewise. * window.c (save_window_save): Likewise. --- src/buffer.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index f73d2d07537..a37a61c0fc8 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -458,11 +458,8 @@ copy_overlays (struct buffer *b, struct Lisp_Overlay *list) static void clone_per_buffer_values (struct buffer *from, struct buffer *to) { - Lisp_Object to_buffer; int offset; - XSETBUFFER (to_buffer, to); - for_each_per_buffer_object_at (offset) { Lisp_Object obj; @@ -475,9 +472,9 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) if (MARKERP (obj) && XMARKER (obj)->buffer == from) { struct Lisp_Marker *m = XMARKER (obj); - obj = Fmake_marker (); + + obj = build_marker (to, m->charpos, m->bytepos); XMARKER (obj)->insertion_type = m->insertion_type; - set_marker_both (obj, to_buffer, m->charpos, m->bytepos); } PER_BUFFER_VALUE (to, offset) = obj; @@ -615,32 +612,24 @@ CLONE nil means the indirect buffer's state is reset to default values. */) eassert (NILP (BVAR (b->base_buffer, begv_marker))); eassert (NILP (BVAR (b->base_buffer, zv_marker))); - BVAR (b->base_buffer, pt_marker) = Fmake_marker (); - set_marker_both (BVAR (b->base_buffer, pt_marker), base_buffer, - b->base_buffer->pt, - b->base_buffer->pt_byte); + BVAR (b->base_buffer, pt_marker) + = build_marker (b->base_buffer, b->base_buffer->pt, b->base_buffer->pt_byte); + + BVAR (b->base_buffer, begv_marker) + = build_marker (b->base_buffer, b->base_buffer->begv, b->base_buffer->begv_byte); - BVAR (b->base_buffer, begv_marker) = Fmake_marker (); - set_marker_both (BVAR (b->base_buffer, begv_marker), base_buffer, - b->base_buffer->begv, - b->base_buffer->begv_byte); + BVAR (b->base_buffer, zv_marker) + = build_marker (b->base_buffer, b->base_buffer->zv, b->base_buffer->zv_byte); - BVAR (b->base_buffer, zv_marker) = Fmake_marker (); - set_marker_both (BVAR (b->base_buffer, zv_marker), base_buffer, - b->base_buffer->zv, - b->base_buffer->zv_byte); XMARKER (BVAR (b->base_buffer, zv_marker))->insertion_type = 1; } if (NILP (clone)) { /* Give the indirect buffer markers for its narrowing. */ - BVAR (b, pt_marker) = Fmake_marker (); - set_marker_both (BVAR (b, pt_marker), buf, b->pt, b->pt_byte); - BVAR (b, begv_marker) = Fmake_marker (); - set_marker_both (BVAR (b, begv_marker), buf, b->begv, b->begv_byte); - BVAR (b, zv_marker) = Fmake_marker (); - set_marker_both (BVAR (b, zv_marker), buf, b->zv, b->zv_byte); + BVAR (b, pt_marker) = build_marker (b, b->pt, b->pt_byte); + BVAR (b, begv_marker) = build_marker (b, b->begv, b->begv_byte); + BVAR (b, zv_marker) = build_marker (b, b->zv, b->zv_byte); XMARKER (BVAR (b, zv_marker))->insertion_type = 1; } else -- cgit v1.2.1 From 7b7ae96547e53a8ba059186fd0b3fd583e8d41cd Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 6 Jul 2012 11:34:37 +0400 Subject: * buffer.c (unchain_overlay): Simplify. Add comment. * marker.c (unchain_marker): Simplify. Fix comments. --- src/buffer.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index a37a61c0fc8..a40270c945c 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3672,18 +3672,17 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) ++BUF_OVERLAY_MODIFF (buf); } - +/* Remove OVERLAY from LIST. */ + static struct Lisp_Overlay * unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay) { - struct Lisp_Overlay *tmp, *prev; - for (tmp = list, prev = NULL; tmp; prev = tmp, tmp = tmp->next) - if (tmp == overlay) + register struct Lisp_Overlay *tail, **prev = &list; + + for (tail = list; tail; prev = &tail->next, tail = *prev) + if (tail == overlay) { - if (prev) - prev->next = tmp->next; - else - list = tmp->next; + *prev = overlay->next; overlay->next = NULL; break; } -- cgit v1.2.1 From a8290ec31c89dfdec85fc9d46000c66c0caa1697 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 9 Jul 2012 16:02:27 +0400 Subject: Use make_formatted_string to avoid double length calculation. * lisp.h (make_formatted_string): New prototype. * alloc.c (make_formatted_string): New function. * buffer.c (Fgenerate_new_buffer_name): Use it. * dbus.c (syms_of_dbusbind): Likewise. * editfns.c (Fcurrent_time_zone): Likewise. * filelock.c (get_boot_time): Likewise. * frame.c (make_terminal_frame, set_term_frame_name) (x_report_frame_params): Likewise. * image.c (gs_load): Likewise. * minibuf.c (get_minibuffer): Likewise. * msdos.c (dos_set_window_size): Likewise. * process.c (make_process): Likewise. * xdisp.c (ensure_echo_area_buffers): Likewise. * xsettings.c (apply_xft_settings): Likewise. --- src/buffer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index a40270c945c..28cede3916c 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -861,8 +861,9 @@ is first appended to NAME, to speed up finding a non-existent buffer. */) if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */ { /* Note fileio.c:make_temp_name does random differently. */ - sprintf (number, "-%"pI"d", XFASTINT (Frandom (make_number (999999)))); - tem2 = concat2 (name, build_string (number)); + tem2 = concat2 (name, make_formatted_string + (number, "-%"pI"d", + XFASTINT (Frandom (make_number (999999))))); tem = Fget_buffer (tem2); if (NILP (tem)) return tem2; @@ -873,8 +874,8 @@ is first appended to NAME, to speed up finding a non-existent buffer. */) count = 1; while (1) { - sprintf (number, "<%"pD"d>", ++count); - gentemp = concat2 (tem2, build_string (number)); + gentemp = concat2 (tem2, make_formatted_string + (number, "<%"pD"d>", ++count)); tem = Fstring_equal (gentemp, ignore); if (!NILP (tem)) return gentemp; -- cgit v1.2.1 From cb1caeaf2ba26df05e8f9bcd4aa63203cef781fb Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 10 Jul 2012 11:59:31 +0400 Subject: Avoid calls to strlen in miscellaneous functions. * buffer.c (init_buffer): Use precalculated len, adjust if needed. * font.c (Ffont_xlfd_name): Likewise. Change to call make_string. * lread.c (openp): Likewise. --- src/buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 28cede3916c..4999639128d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5091,9 +5091,10 @@ init_buffer (void) fatal ("`get_current_dir_name' failed: %s\n", strerror (errno)); pwd[len] = DIRECTORY_SEP; pwd[len + 1] = '\0'; + len++; } - BVAR (current_buffer, directory) = make_unibyte_string (pwd, strlen (pwd)); + BVAR (current_buffer, directory) = make_unibyte_string (pwd, len); if (! NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) /* At this moment, we still don't know how to decode the directory name. So, we keep the bytes in multibyte form so -- cgit v1.2.1 From 2a0213a6d0a9e36a388994445837e051d0bbe5f9 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 10 Jul 2012 12:43:46 +0400 Subject: Optimize pure C strings initialization. * lisp.h (make_pure_string): Fix prototype. (build_pure_c_string): New function, defined as static inline. This provides a better opportunity to optimize away calls to strlen when the function is called with compile-time constant argument. * alloc.c (make_pure_c_string): Fix comment. Change to add nchars argument, adjust users accordingly. Use build_pure_c_string where appropriate. * buffer.c, coding.c, data.c, dbusbind.c, fileio.c, fontset.c, frame.c, * keyboard.c, keymap.c, lread.c, search.c, syntax.c, w32fns.c, xdisp.c, * xfaces.c, xfns.c, xterm.c: Use build_pure_c_string where appropriate. --- src/buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 4999639128d..f06a2a5ea0c 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4898,7 +4898,7 @@ init_buffer_once (void) /* Must do these before making the first buffer! */ /* real setup is done in bindings.el */ - BVAR (&buffer_defaults, mode_line_format) = make_pure_c_string ("%-"); + BVAR (&buffer_defaults, mode_line_format) = build_pure_c_string ("%-"); BVAR (&buffer_defaults, header_line_format) = Qnil; BVAR (&buffer_defaults, abbrev_mode) = Qnil; BVAR (&buffer_defaults, overwrite_mode) = Qnil; @@ -5028,7 +5028,7 @@ init_buffer_once (void) current_buffer = 0; all_buffers = 0; - QSFundamental = make_pure_c_string ("Fundamental"); + QSFundamental = build_pure_c_string ("Fundamental"); Qfundamental_mode = intern_c_string ("fundamental-mode"); BVAR (&buffer_defaults, major_mode) = Qfundamental_mode; @@ -5043,10 +5043,10 @@ init_buffer_once (void) Fput (Qkill_buffer_hook, Qpermanent_local, Qt); /* super-magic invisible buffer */ - Vprin1_to_string_buffer = Fget_buffer_create (make_pure_c_string (" prin1")); + Vprin1_to_string_buffer = Fget_buffer_create (build_pure_c_string (" prin1")); Vbuffer_alist = Qnil; - Fset_buffer (Fget_buffer_create (make_pure_c_string ("*scratch*"))); + Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"))); inhibit_modification_hooks = 0; } @@ -5201,7 +5201,7 @@ syms_of_buffer (void) Fput (Qprotected_field, Qerror_conditions, pure_cons (Qprotected_field, pure_cons (Qerror, Qnil))); Fput (Qprotected_field, Qerror_message, - make_pure_c_string ("Attempt to modify a protected field")); + build_pure_c_string ("Attempt to modify a protected field")); DEFVAR_BUFFER_DEFAULTS ("default-mode-line-format", mode_line_format, -- cgit v1.2.1 From e9a9ae0350689d352c2bdfa3af0eb722f587b966 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 10 Jul 2012 16:24:36 -0700 Subject: EMACS_TIME simplification (Bug#11875). This replaces macros (which typically do not work in GDB) with functions, typedefs and enums, making the code easier to debug. The functional style also makes code easier to read and maintain. * lib-src/profile.c (TV2): Remove no-longer-needed static var. * src/systime.h: Include on all hosts, not just if WINDOWSNT, since 'struct timeval' is needed in general. (EMACS_TIME): Now a typedef, not a macro. (EMACS_TIME_RESOLUTION, LOG10_EMACS_TIME_RESOLUTION): Now constants, not macros. (EMACS_SECS, EMACS_NSECS, EMACS_TIME_SIGN, EMACS_TIME_VALID_P) (EMACS_TIME_FROM_DOUBLE, EMACS_TIME_TO_DOUBLE, EMACS_TIME_EQ) (EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE, EMACS_TIME_LT) (EMACS_TIME_LE): Now functions, not macros. (EMACS_SET_SECS, EMACS_SET_NSECS, EMACS_SET_SECS_NSECS) (EMACS_SET_USECS, EMACS_SET_SECS_USECS): Remove these macros, which are not functions. All uses rewritten to use: (make_emacs_time): New function. (EMACS_SECS_ADDR, EMACS_SET_INVALID_TIME, EMACS_GET_TIME) (EMACS_ADD_TIME, EMACS_SUB_TIME): Remove these macros, which are not functions. All uses rewritten to use the following, respectively: (emacs_secs_addr, invalid_emacs_time, get_emacs_time) (add_emacs_time, sub_emacs_time): New functions. * src/atimer.c: Don't include , as "systime.h" does this. * src/fileio.c (Fcopy_file): * src/xterm.c (XTflash): Get the current time closer to when it's used. * src/makefile.w32-in ($(BLD)/atimer.$(O)): Update dependencies. --- src/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index f06a2a5ea0c..b8c81a10d54 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -705,7 +705,7 @@ reset_buffer (register struct buffer *b) BVAR (b, filename) = Qnil; BVAR (b, file_truename) = Qnil; BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil; - EMACS_SET_SECS_NSECS (b->modtime, 0, UNKNOWN_MODTIME_NSECS); + b->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS); b->modtime_size = -1; XSETFASTINT (BVAR (b, save_length), 0); b->last_window_start = 1; -- cgit v1.2.1 From 8a05d57a7d691085200b64f5e56a6232e78c6ac4 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 12 Jul 2012 09:12:24 +0200 Subject: Fixes: debbugs:11917 Fix crash when creating indirect buffer * buffer.c (buffer_lisp_local_variables): Add argument CLONE. Don't handle unbound variables specially if non-zero. (Fbuffer_local_variables): Pass zero. (clone_per_buffer_values): Pass non-zero. --- src/buffer.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index ac14ec9c37c..88ef34070ea 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -156,7 +156,7 @@ static void alloc_buffer_text (struct buffer *, ptrdiff_t); static void free_buffer_text (struct buffer *b); static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); static void modify_overlay (struct buffer *, EMACS_INT, EMACS_INT); -static Lisp_Object buffer_lisp_local_variables (struct buffer *); +static Lisp_Object buffer_lisp_local_variables (struct buffer *, int); /* For debugging; temporary. See set_buffer_internal. */ /* Lisp_Object Qlisp_mode, Vcheck_symbol; */ @@ -505,7 +505,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) /* Get (a copy of) the alist of Lisp-level local variables of FROM and install that in TO. */ - BVAR (to, local_var_alist) = buffer_lisp_local_variables (from); + BVAR (to, local_var_alist) = buffer_lisp_local_variables (from, 1); } @@ -1003,10 +1003,12 @@ is the default binding of the variable. */) /* Return an alist of the Lisp-level buffer-local bindings of buffer BUF. That is, don't include the variables maintained - in special slots in the buffer object. */ + in special slots in the buffer object. + If CLONE is zero elements of the form (VAR . unbound) are replaced + by VAR. */ static Lisp_Object -buffer_lisp_local_variables (struct buffer *buf) +buffer_lisp_local_variables (struct buffer *buf, int clone) { Lisp_Object result = Qnil; register Lisp_Object tail; @@ -1026,7 +1028,7 @@ buffer_lisp_local_variables (struct buffer *buf) if (buf != current_buffer) val = XCDR (elt); - result = Fcons (EQ (val, Qunbound) + result = Fcons (!clone && EQ (val, Qunbound) ? XCAR (elt) : Fcons (XCAR (elt), val), result); @@ -1055,7 +1057,7 @@ No argument or nil as argument means use current buffer as BUFFER. */) buf = XBUFFER (buffer); } - result = buffer_lisp_local_variables (buf); + result = buffer_lisp_local_variables (buf, 0); /* Add on all the variables stored in special slots. */ { -- cgit v1.2.1 From 22657b40985ec990ea20df878bde97af76b19ed1 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 17 Jul 2012 08:29:50 +0400 Subject: Cleanup overlays checking. * buffer.h (OVERLAY_VALID): Remove as useless synonym of OVERLAYP. * buffer.c (overlay_touches_p, recenter_overlay_lists): Change to eassert and OVERLAYP. (sort_overlays): Change to use OVERLAYP. --- src/buffer.c | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index b8c81a10d54..eaa3d94de34 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2827,8 +2827,7 @@ overlay_touches_p (ptrdiff_t pos) ptrdiff_t endpos; XSETMISC (overlay ,tail); - if (!OVERLAYP (overlay)) - abort (); + eassert (OVERLAYP (overlay)); endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); if (endpos < pos) @@ -2842,8 +2841,7 @@ overlay_touches_p (ptrdiff_t pos) ptrdiff_t startpos; XSETMISC (overlay, tail); - if (!OVERLAYP (overlay)) - abort (); + eassert (OVERLAYP (overlay)); startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); if (pos < startpos) @@ -2898,7 +2896,7 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) Lisp_Object overlay; overlay = overlay_vec[i]; - if (OVERLAY_VALID (overlay) + if (OVERLAYP (overlay) && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) { @@ -3169,22 +3167,7 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) { next = tail->next; XSETMISC (overlay, tail); - - /* If the overlay is not valid, get rid of it. */ - if (!OVERLAY_VALID (overlay)) -#if 1 - abort (); -#else - { - /* Splice the cons cell TAIL out of overlays_before. */ - if (!NILP (prev)) - XCDR (prev) = next; - else - buf->overlays_before = next; - tail = prev; - continue; - } -#endif + eassert (OVERLAYP (overlay)); beg = OVERLAY_START (overlay); end = OVERLAY_END (overlay); @@ -3209,7 +3192,7 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) Lisp_Object otherbeg, otheroverlay; XSETMISC (otheroverlay, other); - eassert (OVERLAY_VALID (otheroverlay)); + eassert (OVERLAYP (otheroverlay)); otherbeg = OVERLAY_START (otheroverlay); if (OVERLAY_POSITION (otherbeg) >= where) @@ -3237,22 +3220,7 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) { next = tail->next; XSETMISC (overlay, tail); - - /* If the overlay is not valid, get rid of it. */ - if (!OVERLAY_VALID (overlay)) -#if 1 - abort (); -#else - { - /* Splice the cons cell TAIL out of overlays_after. */ - if (!NILP (prev)) - XCDR (prev) = next; - else - buf->overlays_after = next; - tail = prev; - continue; - } -#endif + eassert (OVERLAYP (overlay)); beg = OVERLAY_START (overlay); end = OVERLAY_END (overlay); @@ -3282,7 +3250,7 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) Lisp_Object otherend, otheroverlay; XSETMISC (otheroverlay, other); - eassert (OVERLAY_VALID (otheroverlay)); + eassert (OVERLAYP (otheroverlay)); otherend = OVERLAY_END (otheroverlay); if (OVERLAY_POSITION (otherend) <= where) -- cgit v1.2.1 From d17337e501a189c1d46f758e10c6c2842cafff17 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 19 Jul 2012 07:55:59 +0400 Subject: New macro to iterate over all buffers, miscellaneous cleanups. * lisp.h (all_buffers): Remove declaration. * buffer.h (all_buffers): Add declaration, with comment. (for_each_buffer): New macro. * alloc.c (Fgarbage_collect, mark_object): Use it. * buffer.c (Fkill_buffer, Fbuffer_swap_text, Fset_buffer_multibyte) (init_buffer): Likewise. * data.c (Fset_default): Likewise. * coding.c (code_conversion_restore): Remove redundant check for dead buffer. * buffer.c (Fkill_buffer): Likewise. Remove obsolete comment. --- src/buffer.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 1e1bd933f93..40370460b9f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1532,10 +1532,8 @@ cleaning up all windows currently displaying the buffer to be killed. */) GCPRO1 (buffer); - for (other = all_buffers; other; other = other->header.next.buffer) - /* all_buffers contains dead buffers too; - don't re-kill them. */ - if (other->base_buffer == b && !NILP (BVAR (other, name))) + for_each_buffer (other) + if (other->base_buffer == b) { Lisp_Object buf; XSETBUFFER (buf, other); @@ -2052,7 +2050,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, { /* This is probably harder to make work. */ struct buffer *other; - for (other = all_buffers; other; other = other->header.next.buffer) + for_each_buffer (other) if (other->base_buffer == other_buffer || other->base_buffer == current_buffer) error ("One of the buffers to swap has indirect buffers"); @@ -2429,7 +2427,7 @@ current buffer is cleared. */) /* Copy this buffer's new multibyte status into all of its indirect buffers. */ - for (other = all_buffers; other; other = other->header.next.buffer) + for_each_buffer (other) if (other->base_buffer == current_buffer && !NILP (BVAR (other, name))) { BVAR (other, enable_multibyte_characters) @@ -5035,7 +5033,7 @@ init_buffer (void) Map new memory. */ struct buffer *b; - for (b = all_buffers; b; b = b->header.next.buffer) + for_each_buffer (b) if (b->text->beg == NULL) enlarge_buffer_text (b, 0); } -- cgit v1.2.1 From 9cd47b72e021f76a6e2481d986ce4b0cb0b859d3 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 19 Jul 2012 12:56:53 +0400 Subject: Compact buffers when idle. * lisp/compact.el: New file. * src/buffer.c (compact_buffer, Fcompact_buffer): New function. (syms_of_buffer): Register Fcompact_buffer. * src/alloc.c (Fgarbage_collect): Use compact_buffer. * src/buffer.h (compact_buffer): New prototype. (struct buffer_text): New member. --- src/buffer.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 8 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 40370460b9f..0fc5dd0b9c3 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1434,14 +1434,59 @@ No argument or nil as argument means do this for the current buffer. */) return Qnil; } -/* - DEFVAR_LISP ("kill-buffer-hook", ..., "\ -Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\ -The buffer being killed will be current while the hook is running.\n\ +/* Truncate undo list and shrink the gap of BUFFER. */ + +int +compact_buffer (struct buffer *buffer) +{ + /* Skip dead buffers, indirect buffers and buffers + which aren't changed since last compaction. */ + if (!NILP (buffer->BUFFER_INTERNAL_FIELD (name)) + && (buffer->base_buffer == NULL) + && (buffer->text->compact != buffer->text->modiff)) + { + /* If a buffer's undo list is Qt, that means that undo is + turned off in that buffer. Calling truncate_undo_list on + Qt tends to return NULL, which effectively turns undo back on. + So don't call truncate_undo_list if undo_list is Qt. */ + if (!EQ (buffer->BUFFER_INTERNAL_FIELD (undo_list), Qt)) + truncate_undo_list (buffer); + + /* Shrink buffer gaps. */ + if (!buffer->text->inhibit_shrinking) + { + /* If a buffer's gap size is more than 10% of the buffer + size, or larger than 2000 bytes, then shrink it + accordingly. Keep a minimum size of 20 bytes. */ + int size = min (2000, max (20, (buffer->text->z_byte / 10))); + + if (buffer->text->gap_size > size) + { + struct buffer *save_current = current_buffer; + current_buffer = buffer; + make_gap (-(buffer->text->gap_size - size)); + current_buffer = save_current; + } + } + buffer->text->compact = buffer->text->modiff; + return 1; + } + return 0; +} + +DEFUN ("compact-buffer", Fcompact_buffer, Scompact_buffer, 0, 1, 0, + doc: /* Compact BUFFER by truncating undo list and shrinking the gap. +If buffer is nil, compact current buffer. Compaction is performed +only if buffer was changed since last compaction. Return t if +buffer compaction was performed, and nil otherwise. */) + (Lisp_Object buffer) +{ + if (NILP (buffer)) + XSETBUFFER (buffer, current_buffer); + CHECK_BUFFER (buffer); + return compact_buffer (XBUFFER (buffer)) ? Qt : Qnil; +} -Functions run by this hook are supposed to not change the current -buffer. See `kill-buffer'." -*/ DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ", doc: /* Kill the buffer specified by BUFFER-OR-NAME. The argument may be a buffer or the name of an existing buffer. @@ -5992,7 +6037,6 @@ and `bury-buffer-internal'. */); defsubr (&Smake_indirect_buffer); defsubr (&Sgenerate_new_buffer_name); defsubr (&Sbuffer_name); -/*defsubr (&Sbuffer_number);*/ defsubr (&Sbuffer_file_name); defsubr (&Sbuffer_base_buffer); defsubr (&Sbuffer_local_value); @@ -6004,6 +6048,7 @@ and `bury-buffer-internal'. */); defsubr (&Srename_buffer); defsubr (&Sother_buffer); defsubr (&Sbuffer_enable_undo); + defsubr (&Scompact_buffer); defsubr (&Skill_buffer); defsubr (&Sbury_buffer_internal); defsubr (&Sset_buffer_major_mode); -- cgit v1.2.1 From 52b852c77d74800aaa1338dc72f786f7e261bfee Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 19 Jul 2012 15:35:58 -0700 Subject: * buffer.h (FOR_EACH_BUFFER): Rename from 'for_each_buffer'. (FOR_EACH_PER_BUFFER_OBJECT_AT): Rename from 'for_each_per_buffer_object_at'. All uses changed. It's better to use upper-case for macros that cannot be implemented as functions, to give the reader a clue that they're special. --- src/buffer.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 0fc5dd0b9c3..04d83d76945 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -460,7 +460,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) { int offset; - for_each_per_buffer_object_at (offset) + FOR_EACH_PER_BUFFER_OBJECT_AT (offset) { Lisp_Object obj; @@ -612,7 +612,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) eassert (NILP (BVAR (b->base_buffer, begv_marker))); eassert (NILP (BVAR (b->base_buffer, zv_marker))); - BVAR (b->base_buffer, pt_marker) + BVAR (b->base_buffer, pt_marker) = build_marker (b->base_buffer, b->base_buffer->pt, b->base_buffer->pt_byte); BVAR (b->base_buffer, begv_marker) @@ -817,7 +817,7 @@ reset_buffer_local_variables (register struct buffer *b, int permanent_too) SET_PER_BUFFER_VALUE_P (b, i, 0); /* For each slot that has a default value, copy that into the slot. */ - for_each_per_buffer_object_at (offset) + FOR_EACH_PER_BUFFER_OBJECT_AT (offset) { int idx = PER_BUFFER_IDX (offset); if ((idx > 0 @@ -862,7 +862,7 @@ is first appended to NAME, to speed up finding a non-existent buffer. */) { /* Note fileio.c:make_temp_name does random differently. */ tem2 = concat2 (name, make_formatted_string - (number, "-%"pI"d", + (number, "-%"pI"d", XFASTINT (Frandom (make_number (999999))))); tem = Fget_buffer (tem2); if (NILP (tem)) @@ -1072,7 +1072,7 @@ No argument or nil as argument means use current buffer as BUFFER. */) { int offset, idx; - for_each_per_buffer_object_at (offset) + FOR_EACH_PER_BUFFER_OBJECT_AT (offset) { idx = PER_BUFFER_IDX (offset); if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) @@ -1577,7 +1577,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) GCPRO1 (buffer); - for_each_buffer (other) + FOR_EACH_BUFFER (other) if (other->base_buffer == b) { Lisp_Object buf; @@ -2095,7 +2095,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, { /* This is probably harder to make work. */ struct buffer *other; - for_each_buffer (other) + FOR_EACH_BUFFER (other) if (other->base_buffer == other_buffer || other->base_buffer == current_buffer) error ("One of the buffers to swap has indirect buffers"); @@ -2472,7 +2472,7 @@ current buffer is cleared. */) /* Copy this buffer's new multibyte status into all of its indirect buffers. */ - for_each_buffer (other) + FOR_EACH_BUFFER (other) if (other->base_buffer == current_buffer && !NILP (BVAR (other, name))) { BVAR (other, enable_multibyte_characters) @@ -5078,7 +5078,7 @@ init_buffer (void) Map new memory. */ struct buffer *b; - for_each_buffer (b) + FOR_EACH_BUFFER (b) if (b->text->beg == NULL) enlarge_buffer_text (b, 0); } -- cgit v1.2.1 From f8643a6b9e35af22b69a84f83df5d9410de82f16 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 20 Jul 2012 18:07:28 +0400 Subject: Extend the value returned by Fgarbage_collect with heap statistics. * alloc.c (Qheap): New symbol. (syms_of_alloc): DEFSYM it. (Fgarbage_collect): If DOUG_LEA_MALLOC, add mallinfo data. (Fmemory_free): Remove. (syms_of_alloc): Don't defsubr it. * buffer.c (Fcompact_buffer): Remove. (syms_of_buffer): Don't defsubr it. --- src/buffer.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 04d83d76945..b722ff135dd 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1474,19 +1474,6 @@ compact_buffer (struct buffer *buffer) return 0; } -DEFUN ("compact-buffer", Fcompact_buffer, Scompact_buffer, 0, 1, 0, - doc: /* Compact BUFFER by truncating undo list and shrinking the gap. -If buffer is nil, compact current buffer. Compaction is performed -only if buffer was changed since last compaction. Return t if -buffer compaction was performed, and nil otherwise. */) - (Lisp_Object buffer) -{ - if (NILP (buffer)) - XSETBUFFER (buffer, current_buffer); - CHECK_BUFFER (buffer); - return compact_buffer (XBUFFER (buffer)) ? Qt : Qnil; -} - DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ", doc: /* Kill the buffer specified by BUFFER-OR-NAME. The argument may be a buffer or the name of an existing buffer. @@ -6048,7 +6035,6 @@ and `bury-buffer-internal'. */); defsubr (&Srename_buffer); defsubr (&Sother_buffer); defsubr (&Sbuffer_enable_undo); - defsubr (&Scompact_buffer); defsubr (&Skill_buffer); defsubr (&Sbury_buffer_internal); defsubr (&Sset_buffer_major_mode); -- cgit v1.2.1 From 9928463dcdb0164477785e83406602065de79ef8 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 20 Jul 2012 20:05:47 +0400 Subject: Add indirection counting to speed up Fkill_buffer. * buffer.h (struct buffer): New member. * buffer.c (Fget_buffer_create): Set indirection counter to 0. (Fmake_indirect_buffer): Set indirection counter to -1, increment base buffer indirection counter. (compact_buffer): If ENABLE_CHECKING, verify indirection counters. (Fkill_buffer): Adjust indirection counters as needed, don't walk through buffer list if indirection counter is 0. --- src/buffer.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index b722ff135dd..5f9f6a79b67 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -329,7 +329,9 @@ even if it is dead. The return value is never nil. */) /* An ordinary buffer uses its own struct buffer_text. */ b->text = &b->own_text; - b->base_buffer = 0; + b->base_buffer = NULL; + /* No one shares the text with us now. */ + b->indirections = 0; BUF_GAP_SIZE (b) = 20; BLOCK_INPUT; @@ -568,12 +570,18 @@ CLONE nil means the indirect buffer's state is reset to default values. */) b = allocate_buffer (); + /* No double indirection - if base buffer is indirect, + new buffer becomes an indirect to base's base. */ b->base_buffer = (XBUFFER (base_buffer)->base_buffer ? XBUFFER (base_buffer)->base_buffer : XBUFFER (base_buffer)); /* Use the base buffer's text object. */ b->text = b->base_buffer->text; + /* We have no own text. */ + b->indirections = -1; + /* Notify base buffer that we share the text now. */ + b->base_buffer->indirections++; b->pt = b->base_buffer->pt; b->begv = b->base_buffer->begv; @@ -1439,6 +1447,15 @@ No argument or nil as argument means do this for the current buffer. */) int compact_buffer (struct buffer *buffer) { + /* Verify indirection counters. */ + if (buffer->base_buffer) + { + eassert (buffer->indirections == -1); + eassert (buffer->base_buffer->indirections > 0); + } + else + eassert (buffer->indirections >= 0); + /* Skip dead buffers, indirect buffers and buffers which aren't changed since last compaction. */ if (!NILP (buffer->BUFFER_INTERNAL_FIELD (name)) @@ -1555,10 +1572,19 @@ cleaning up all windows currently displaying the buffer to be killed. */) if (EQ (buffer, XWINDOW (minibuf_window)->buffer)) return Qnil; - /* When we kill a base buffer, kill all its indirect buffers. + /* Notify our base buffer that we don't share the text anymore. */ + if (b->base_buffer) + { + eassert (b->indirections == -1); + b->base_buffer->indirections--; + eassert (b->base_buffer->indirections >= 0); + } + + /* When we kill an ordinary buffer which shares it's buffer text + with indirect buffer(s), we must kill indirect buffer(s) too. We do it at this stage so nothing terrible happens if they ask questions or their hooks get errors. */ - if (! b->base_buffer) + if (!b->base_buffer && b->indirections > 0) { struct buffer *other; -- cgit v1.2.1 From 372f8ffc2eaea40d98a15242482a8c771de70dd4 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 23 Jul 2012 11:14:58 +0400 Subject: Swap buffer text indirection counters in Fbuffer_swap_text. * buffer.c (Fbuffer_swap_text): Swap indirections too. This avoids crash reported by Christoph Scholtes at http://lists.gnu.org/archive/html/bug-gnu-emacs/2012-07/msg00785.html. --- src/buffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 5f9f6a79b67..68208d17abe 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2145,6 +2145,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, swapfield (zv_byte, ptrdiff_t); eassert (!current_buffer->base_buffer); eassert (!other_buffer->base_buffer); + swapfield (indirections, ptrdiff_t); current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; swapfield (newline_cache, struct region_cache *); swapfield (width_run_cache, struct region_cache *); -- cgit v1.2.1 From d7a7fda3cc130edb8bc10af96d322d263afbb44a Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 23 Jul 2012 15:15:43 +0400 Subject: Cleanup miscellaneous objects allocation and initialization. * alloc.c (allocate_misc): Change to static. Add argument to specify the subtype. Adjust comment and users. (build_overlay): New function. * buffer.c (copy_overlays, Fmake_overlay): Use it. * lisp.h (struct Lisp_Overlay): Remove obsolete comment. (allocate_misc): Remove prototype. (build_overlay): Add prototype. --- src/buffer.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 68208d17abe..734ddb5a1c1 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -433,12 +433,8 @@ copy_overlays (struct buffer *b, struct Lisp_Overlay *list) XMARKER (end)->insertion_type = XMARKER (OVERLAY_END (old_overlay))->insertion_type; - overlay = allocate_misc (); - XMISCTYPE (overlay) = Lisp_Misc_Overlay; - OVERLAY_START (overlay) = start; - OVERLAY_END (overlay) = end; - OVERLAY_PLIST (overlay) = Fcopy_sequence (OVERLAY_PLIST (old_overlay)); - XOVERLAY (overlay)->next = NULL; + overlay = build_overlay + (start, end, Fcopy_sequence (OVERLAY_PLIST (old_overlay))); if (tail) tail = tail->next = XOVERLAY (overlay); @@ -3640,12 +3636,7 @@ for the rear of the overlay advance when text is inserted there if (!NILP (rear_advance)) XMARKER (end)->insertion_type = 1; - overlay = allocate_misc (); - XMISCTYPE (overlay) = Lisp_Misc_Overlay; - XOVERLAY (overlay)->start = beg; - XOVERLAY (overlay)->end = end; - XOVERLAY (overlay)->plist = Qnil; - XOVERLAY (overlay)->next = NULL; + overlay = build_overlay (beg, end, Qnil); /* Put the new overlay on the wrong list. */ end = OVERLAY_END (overlay); -- cgit v1.2.1 From fa691a83f0f67db762d8d8d9d05d9ff97f25841f Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 24 Jul 2012 10:45:44 +0400 Subject: Simplify copy_overlay. * buffer.c (copy_overlay): Simplify, use build_marker. * lisp.h (struct Lisp_Overlay): Restore comment with minor tweaks. --- src/buffer.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 734ddb5a1c1..c017db7b034 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -410,32 +410,24 @@ even if it is dead. The return value is never nil. */) static struct Lisp_Overlay * copy_overlays (struct buffer *b, struct Lisp_Overlay *list) { - Lisp_Object buffer; struct Lisp_Overlay *result = NULL, *tail = NULL; - XSETBUFFER (buffer, b); - for (; list; list = list->next) { - Lisp_Object overlay, start, end, old_overlay; - ptrdiff_t charpos; - - XSETMISC (old_overlay, list); - charpos = marker_position (OVERLAY_START (old_overlay)); - start = Fmake_marker (); - Fset_marker (start, make_number (charpos), buffer); - XMARKER (start)->insertion_type - = XMARKER (OVERLAY_START (old_overlay))->insertion_type; + Lisp_Object overlay, start, end; + struct Lisp_Marker *m; - charpos = marker_position (OVERLAY_END (old_overlay)); - end = Fmake_marker (); - Fset_marker (end, make_number (charpos), buffer); - XMARKER (end)->insertion_type - = XMARKER (OVERLAY_END (old_overlay))->insertion_type; + eassert (MARKERP (list->start)); + m = XMARKER (list->start); + start = build_marker (b, m->charpos, m->bytepos); + XMARKER (start)->insertion_type = m->insertion_type; - overlay = build_overlay - (start, end, Fcopy_sequence (OVERLAY_PLIST (old_overlay))); + eassert (MARKERP (list->end)); + m = XMARKER (list->end); + end = build_marker (b, m->charpos, m->bytepos); + XMARKER (end)->insertion_type = m->insertion_type; + overlay = build_overlay (start, end, Fcopy_sequence (list->plist)); if (tail) tail = tail->next = XOVERLAY (overlay); else -- cgit v1.2.1 From 04e9897cf70e46c703b1412d022511e80314a720 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 25 Jul 2012 09:09:02 +0400 Subject: Adjust buffer text indirection counters at the end of Fkill_buffer. * buffer.c (Fkill_buffer): Adjust indirection counters when the buffer is definitely dead. This should really fix an issue reported by Christoph Scholtes again. (Bug#12007). (init_buffer_once): Initialize indirection counters of buffer_defaults and buffer_local_symbols (for sanity and safety). --- src/buffer.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index c017db7b034..06d385110c6 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1560,14 +1560,6 @@ cleaning up all windows currently displaying the buffer to be killed. */) if (EQ (buffer, XWINDOW (minibuf_window)->buffer)) return Qnil; - /* Notify our base buffer that we don't share the text anymore. */ - if (b->base_buffer) - { - eassert (b->indirections == -1); - b->base_buffer->indirections--; - eassert (b->base_buffer->indirections >= 0); - } - /* When we kill an ordinary buffer which shares it's buffer text with indirect buffer(s), we must kill indirect buffer(s) too. We do it at this stage so nothing terrible happens if they @@ -1708,7 +1700,15 @@ cleaning up all windows currently displaying the buffer to be killed. */) BVAR (b, name) = Qnil; BLOCK_INPUT; - if (! b->base_buffer) + if (b->base_buffer) + { + /* Notify our base buffer that we don't share the text anymore. */ + eassert (b->indirections == -1); + b->base_buffer->indirections--; + eassert (b->base_buffer->indirections >= 0); + } + else + /* No one shares our buffer text, can free it. */ free_buffer_text (b); if (b->newline_cache) @@ -4897,6 +4897,9 @@ init_buffer_once (void) /* Prevent GC from getting confused. */ buffer_defaults.text = &buffer_defaults.own_text; buffer_local_symbols.text = &buffer_local_symbols.own_text; + /* No one will share the text with these buffers, but let's play it safe. */ + buffer_defaults.indirections = 0; + buffer_local_symbols.indirections = 0; BUF_INTERVALS (&buffer_defaults) = 0; BUF_INTERVALS (&buffer_local_symbols) = 0; XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize); -- cgit v1.2.1