aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c106
-rw-r--r--src/buffer.c55
-rw-r--r--src/buffer.h12
-rw-r--r--src/pdumper.c2
4 files changed, 49 insertions, 126 deletions
diff --git a/src/alloc.c b/src/alloc.c
index eed73bcdc4e..cc9ba8dbf50 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -432,7 +432,6 @@ inline static void set_interval_marked (INTERVAL i);
432enum mem_type 432enum mem_type
433{ 433{
434 MEM_TYPE_NON_LISP, 434 MEM_TYPE_NON_LISP,
435 MEM_TYPE_BUFFER,
436 MEM_TYPE_CONS, 435 MEM_TYPE_CONS,
437 MEM_TYPE_STRING, 436 MEM_TYPE_STRING,
438 MEM_TYPE_SYMBOL, 437 MEM_TYPE_SYMBOL,
@@ -3331,12 +3330,10 @@ allocate_pseudovector (int memlen, int lisplen,
3331struct buffer * 3330struct buffer *
3332allocate_buffer (void) 3331allocate_buffer (void)
3333{ 3332{
3334 struct buffer *b = lisp_malloc (sizeof *b, false, MEM_TYPE_BUFFER); 3333 struct buffer *b
3335 3334 = ALLOCATE_PSEUDOVECTOR (struct buffer, cursor_in_non_selected_windows_,
3335 PVEC_BUFFER);
3336 BUFFER_PVEC_INIT (b); 3336 BUFFER_PVEC_INIT (b);
3337 /* Put B on the chain of all buffers including killed ones. */
3338 b->next = all_buffers;
3339 all_buffers = b;
3340 /* Note that the rest fields of B are not initialized. */ 3337 /* Note that the rest fields of B are not initialized. */
3341 return b; 3338 return b;
3342} 3339}
@@ -4596,40 +4593,6 @@ live_vector_p (struct mem_node *m, void *p)
4596 return !NILP (live_vector_holding (m, p)); 4593 return !NILP (live_vector_holding (m, p));
4597} 4594}
4598 4595
4599/* If P is a pointer into a valid buffer object, return the buffer.
4600 Otherwise, return nil. M is a pointer to the mem_block for P.
4601 If IGNORE_KILLED is non-zero, treat killed buffers as invalid. */
4602
4603static Lisp_Object
4604live_buffer_holding (struct mem_node *m, void *p, bool ignore_killed)
4605{
4606 /* P must point into the block, and the buffer must not
4607 have been killed unless ALL-BUFFERS is true. */
4608 if (m->type == MEM_TYPE_BUFFER)
4609 {
4610 struct buffer *b = m->start;
4611 char *cb = m->start;
4612 char *cp = p;
4613 ptrdiff_t offset = cp - cb;
4614 if (0 <= offset && offset < sizeof *b
4615 && !(ignore_killed && NILP (b->name_)))
4616 {
4617 Lisp_Object obj;
4618 XSETBUFFER (obj, b);
4619 return obj;
4620 }
4621 }
4622 return Qnil;
4623}
4624
4625/* If P is a pointer into a live (valid and not killed) buffer object,
4626 return non-zero. */
4627static bool
4628live_buffer_p (struct mem_node *m, void *p)
4629{
4630 return !NILP (live_buffer_holding (m, p, true));
4631}
4632
4633/* Mark OBJ if we can prove it's a Lisp_Object. */ 4596/* Mark OBJ if we can prove it's a Lisp_Object. */
4634 4597
4635static void 4598static void
@@ -4684,8 +4647,7 @@ mark_maybe_object (Lisp_Object obj)
4684 break; 4647 break;
4685 4648
4686 case Lisp_Vectorlike: 4649 case Lisp_Vectorlike:
4687 mark_p = (EQ (obj, live_vector_holding (m, po)) 4650 mark_p = (EQ (obj, live_vector_holding (m, po)));
4688 || EQ (obj, live_buffer_holding (m, po, false)));
4689 break; 4651 break;
4690 4652
4691 default: 4653 default:
@@ -4754,10 +4716,6 @@ mark_maybe_pointer (void *p)
4754 /* Nothing to do; not a pointer to Lisp memory. */ 4716 /* Nothing to do; not a pointer to Lisp memory. */
4755 break; 4717 break;
4756 4718
4757 case MEM_TYPE_BUFFER:
4758 obj = live_buffer_holding (m, p, false);
4759 break;
4760
4761 case MEM_TYPE_CONS: 4719 case MEM_TYPE_CONS:
4762 obj = live_cons_holding (m, p); 4720 obj = live_cons_holding (m, p);
4763 break; 4721 break;
@@ -5157,9 +5115,6 @@ valid_lisp_object_p (Lisp_Object obj)
5157 case MEM_TYPE_SPARE: 5115 case MEM_TYPE_SPARE:
5158 return 0; 5116 return 0;
5159 5117
5160 case MEM_TYPE_BUFFER:
5161 return live_buffer_p (m, p) ? 1 : 2;
5162
5163 case MEM_TYPE_CONS: 5118 case MEM_TYPE_CONS:
5164 return live_cons_p (m, p); 5119 return live_cons_p (m, p);
5165 5120
@@ -5976,7 +5931,7 @@ maybe_garbage_collect (void)
5976void 5931void
5977garbage_collect (void) 5932garbage_collect (void)
5978{ 5933{
5979 struct buffer *nextb; 5934 Lisp_Object tail, buffer;
5980 char stack_top_variable; 5935 char stack_top_variable;
5981 bool message_p; 5936 bool message_p;
5982 ptrdiff_t count = SPECPDL_INDEX (); 5937 ptrdiff_t count = SPECPDL_INDEX ();
@@ -5992,8 +5947,8 @@ garbage_collect (void)
5992 5947
5993 /* Don't keep undo information around forever. 5948 /* Don't keep undo information around forever.
5994 Do this early on, so it is no problem if the user quits. */ 5949 Do this early on, so it is no problem if the user quits. */
5995 FOR_EACH_BUFFER (nextb) 5950 FOR_EACH_LIVE_BUFFER (tail, buffer)
5996 compact_buffer (nextb); 5951 compact_buffer (XBUFFER (buffer));
5997 5952
5998 byte_ct tot_before = (profiler_memory_running 5953 byte_ct tot_before = (profiler_memory_running
5999 ? total_bytes_of_live_objects () 5954 ? total_bytes_of_live_objects ()
@@ -6083,8 +6038,9 @@ garbage_collect (void)
6083 6038
6084 compact_font_caches (); 6039 compact_font_caches ();
6085 6040
6086 FOR_EACH_BUFFER (nextb) 6041 FOR_EACH_LIVE_BUFFER (tail, buffer)
6087 { 6042 {
6043 struct buffer *nextb = XBUFFER (buffer);
6088 if (!EQ (BVAR (nextb, undo_list), Qt)) 6044 if (!EQ (BVAR (nextb, undo_list), Qt))
6089 bset_undo_list (nextb, compact_undo_list (BVAR (nextb, undo_list))); 6045 bset_undo_list (nextb, compact_undo_list (BVAR (nextb, undo_list)));
6090 /* Now that we have stripped the elements that need not be 6046 /* Now that we have stripped the elements that need not be
@@ -6349,7 +6305,12 @@ mark_buffer (struct buffer *buffer)
6349 6305
6350 /* For now, we just don't mark the undo_list. It's done later in 6306 /* For now, we just don't mark the undo_list. It's done later in
6351 a special way just before the sweep phase, and after stripping 6307 a special way just before the sweep phase, and after stripping
6352 some of its elements that are not needed any more. */ 6308 some of its elements that are not needed any more.
6309 Note: this later processing is only done for live buffers, so
6310 for dead buffers, the undo_list should be nil (set by Fkill_buffer),
6311 but just to be on the safe side, we mark it here. */
6312 if (!BUFFER_LIVE_P (buffer))
6313 mark_object (BVAR (buffer, undo_list));
6353 6314
6354 mark_overlay (buffer->overlays_before); 6315 mark_overlay (buffer->overlays_before);
6355 mark_overlay (buffer->overlays_after); 6316 mark_overlay (buffer->overlays_after);
@@ -6613,23 +6574,12 @@ mark_object (Lisp_Object arg)
6613 = PSEUDOVECTOR_TYPE (ptr); 6574 = PSEUDOVECTOR_TYPE (ptr);
6614 6575
6615 if (pvectype != PVEC_SUBR && 6576 if (pvectype != PVEC_SUBR &&
6616 pvectype != PVEC_BUFFER &&
6617 !main_thread_p (po)) 6577 !main_thread_p (po))
6618 CHECK_LIVE (live_vector_p); 6578 CHECK_LIVE (live_vector_p);
6619 6579
6620 switch (pvectype) 6580 switch (pvectype)
6621 { 6581 {
6622 case PVEC_BUFFER: 6582 case PVEC_BUFFER:
6623#if GC_CHECK_MARKED_OBJECTS
6624 {
6625 struct buffer *b;
6626 FOR_EACH_BUFFER (b)
6627 if (b == po)
6628 break;
6629 if (b == NULL)
6630 emacs_abort ();
6631 }
6632#endif /* GC_CHECK_MARKED_OBJECTS */
6633 mark_buffer ((struct buffer *) ptr); 6583 mark_buffer ((struct buffer *) ptr);
6634 break; 6584 break;
6635 6585
@@ -7108,25 +7058,17 @@ NO_INLINE /* For better stack traces */
7108static void 7058static void
7109sweep_buffers (void) 7059sweep_buffers (void)
7110{ 7060{
7111 struct buffer *buffer, **bprev = &all_buffers; 7061 Lisp_Object tail, buf;
7112 7062
7113 gcstat.total_buffers = 0; 7063 gcstat.total_buffers = 0;
7114 for (buffer = all_buffers; buffer; buffer = *bprev) 7064 FOR_EACH_LIVE_BUFFER (tail, buf)
7115 if (!vectorlike_marked_p (&buffer->header)) 7065 {
7116 { 7066 struct buffer *buffer = XBUFFER (buf);
7117 *bprev = buffer->next; 7067 /* Do not use buffer_(set|get)_intervals here. */
7118 lisp_free (buffer); 7068 buffer->text->intervals = balance_intervals (buffer->text->intervals);
7119 } 7069 unchain_dead_markers (buffer);
7120 else 7070 gcstat.total_buffers++;
7121 { 7071 }
7122 if (!pdumper_object_p (buffer))
7123 XUNMARK_VECTOR (buffer);
7124 /* Do not use buffer_(set|get)_intervals here. */
7125 buffer->text->intervals = balance_intervals (buffer->text->intervals);
7126 unchain_dead_markers (buffer);
7127 gcstat.total_buffers++;
7128 bprev = &buffer->next;
7129 }
7130} 7072}
7131 7073
7132/* Sweep: find all structures not marked, and free them. */ 7074/* Sweep: find all structures not marked, and free them. */
diff --git a/src/buffer.c b/src/buffer.c
index 4e121ca4cab..d8842a6d770 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -51,11 +51,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
51#include "w32heap.h" /* for mmap_* */ 51#include "w32heap.h" /* for mmap_* */
52#endif 52#endif
53 53
54/* First buffer in chain of all buffers (in reverse order of creation).
55 Threaded through ->header.next.buffer. */
56
57struct buffer *all_buffers;
58
59/* This structure holds the default values of the buffer-local variables 54/* This structure holds the default values of the buffer-local variables
60 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer. 55 defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.
61 The default value occupies the same slot in this structure 56 The default value occupies the same slot in this structure
@@ -1786,15 +1781,11 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1786 ask questions or their hooks get errors. */ 1781 ask questions or their hooks get errors. */
1787 if (!b->base_buffer && b->indirections > 0) 1782 if (!b->base_buffer && b->indirections > 0)
1788 { 1783 {
1789 struct buffer *other; 1784 Lisp_Object tail, other;
1790 1785
1791 FOR_EACH_BUFFER (other) 1786 FOR_EACH_LIVE_BUFFER (tail, other)
1792 if (other->base_buffer == b) 1787 if (XBUFFER (other)->base_buffer == b)
1793 { 1788 Fkill_buffer (other);
1794 Lisp_Object buf;
1795 XSETBUFFER (buf, other);
1796 Fkill_buffer (buf);
1797 }
1798 1789
1799 /* Exit if we now have killed the base buffer (Bug#11665). */ 1790 /* Exit if we now have killed the base buffer (Bug#11665). */
1800 if (!BUFFER_LIVE_P (b)) 1791 if (!BUFFER_LIVE_P (b))
@@ -1849,6 +1840,9 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1849 1840
1850 tem = Vinhibit_quit; 1841 tem = Vinhibit_quit;
1851 Vinhibit_quit = Qt; 1842 Vinhibit_quit = Qt;
1843 /* Once the buffer is removed from Vbuffer_alist, its undo_list field is
1844 not traced by the GC in the same way. So set it to nil early. */
1845 bset_undo_list (b, Qnil);
1852 /* Remove the buffer from the list of all buffers. */ 1846 /* Remove the buffer from the list of all buffers. */
1853 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist); 1847 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
1854 /* If replace_buffer_in_windows didn't do its job fix that now. */ 1848 /* If replace_buffer_in_windows didn't do its job fix that now. */
@@ -1963,7 +1957,6 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1963 } 1957 }
1964 bset_width_table (b, Qnil); 1958 bset_width_table (b, Qnil);
1965 unblock_input (); 1959 unblock_input ();
1966 bset_undo_list (b, Qnil);
1967 1960
1968 /* Run buffer-list-update-hook. */ 1961 /* Run buffer-list-update-hook. */
1969 if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks) 1962 if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks)
@@ -2351,10 +2344,10 @@ results, see Info node `(elisp)Swapping Text'. */)
2351 error ("Cannot swap indirect buffers's text"); 2344 error ("Cannot swap indirect buffers's text");
2352 2345
2353 { /* This is probably harder to make work. */ 2346 { /* This is probably harder to make work. */
2354 struct buffer *other; 2347 Lisp_Object tail, other;
2355 FOR_EACH_BUFFER (other) 2348 FOR_EACH_LIVE_BUFFER (tail, other)
2356 if (other->base_buffer == other_buffer 2349 if (XBUFFER (other)->base_buffer == other_buffer
2357 || other->base_buffer == current_buffer) 2350 || XBUFFER (other)->base_buffer == current_buffer)
2358 error ("One of the buffers to swap has indirect buffers"); 2351 error ("One of the buffers to swap has indirect buffers");
2359 } 2352 }
2360 2353
@@ -2502,7 +2495,7 @@ current buffer is cleared. */)
2502 (Lisp_Object flag) 2495 (Lisp_Object flag)
2503{ 2496{
2504 struct Lisp_Marker *tail, *markers; 2497 struct Lisp_Marker *tail, *markers;
2505 struct buffer *other; 2498 Lisp_Object btail, other;
2506 ptrdiff_t begv, zv; 2499 ptrdiff_t begv, zv;
2507 bool narrowed = (BEG != BEGV || Z != ZV); 2500 bool narrowed = (BEG != BEGV || Z != ZV);
2508 bool modified_p = !NILP (Fbuffer_modified_p (Qnil)); 2501 bool modified_p = !NILP (Fbuffer_modified_p (Qnil));
@@ -2755,13 +2748,16 @@ current buffer is cleared. */)
2755 2748
2756 /* Copy this buffer's new multibyte status 2749 /* Copy this buffer's new multibyte status
2757 into all of its indirect buffers. */ 2750 into all of its indirect buffers. */
2758 FOR_EACH_BUFFER (other) 2751 FOR_EACH_LIVE_BUFFER (btail, other)
2759 if (other->base_buffer == current_buffer && BUFFER_LIVE_P (other)) 2752 {
2760 { 2753 struct buffer *o = XBUFFER (other);
2761 BVAR (other, enable_multibyte_characters) 2754 if (o->base_buffer == current_buffer && BUFFER_LIVE_P (o))
2762 = BVAR (current_buffer, enable_multibyte_characters); 2755 {
2763 other->prevent_redisplay_optimizations_p = 1; 2756 BVAR (o, enable_multibyte_characters)
2764 } 2757 = BVAR (current_buffer, enable_multibyte_characters);
2758 o->prevent_redisplay_optimizations_p = true;
2759 }
2760 }
2765 2761
2766 /* Restore the modifiedness of the buffer. */ 2762 /* Restore the modifiedness of the buffer. */
2767 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil))) 2763 if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
@@ -5327,8 +5323,6 @@ init_buffer_once (void)
5327 Vbuffer_alist = Qnil; 5323 Vbuffer_alist = Qnil;
5328 current_buffer = 0; 5324 current_buffer = 0;
5329 pdumper_remember_lv_ptr_raw (&current_buffer, Lisp_Vectorlike); 5325 pdumper_remember_lv_ptr_raw (&current_buffer, Lisp_Vectorlike);
5330 all_buffers = 0;
5331 pdumper_remember_lv_ptr_raw (&all_buffers, Lisp_Vectorlike);
5332 5326
5333 QSFundamental = build_pure_c_string ("Fundamental"); 5327 QSFundamental = build_pure_c_string ("Fundamental");
5334 5328
@@ -5359,7 +5353,7 @@ init_buffer (void)
5359#ifdef USE_MMAP_FOR_BUFFERS 5353#ifdef USE_MMAP_FOR_BUFFERS
5360 if (dumped_with_unexec_p ()) 5354 if (dumped_with_unexec_p ())
5361 { 5355 {
5362 struct buffer *b; 5356 Lisp_Object tail, buffer;
5363 5357
5364#ifndef WINDOWSNT 5358#ifndef WINDOWSNT
5365 /* These must be reset in the dumped Emacs, to avoid stale 5359 /* These must be reset in the dumped Emacs, to avoid stale
@@ -5381,8 +5375,9 @@ init_buffer (void)
5381 " *code-conversion-work*". They are created by 5375 " *code-conversion-work*". They are created by
5382 init_buffer_once and init_window_once (which are not called 5376 init_buffer_once and init_window_once (which are not called
5383 in the dumped Emacs), and by the first call to coding.c routines. */ 5377 in the dumped Emacs), and by the first call to coding.c routines. */
5384 FOR_EACH_BUFFER (b) 5378 FOR_EACH_LIVE_BUFFER (tail, buffer)
5385 { 5379 {
5380 struct buffer *b = XBUFFER (buffer);
5386 b->text->beg = NULL; 5381 b->text->beg = NULL;
5387 enlarge_buffer_text (b, 0); 5382 enlarge_buffer_text (b, 0);
5388 } 5383 }
diff --git a/src/buffer.h b/src/buffer.h
index 31f497ea40a..abb1294d038 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -570,9 +570,6 @@ struct buffer
570 In an indirect buffer, this is the own_text field of another buffer. */ 570 In an indirect buffer, this is the own_text field of another buffer. */
571 struct buffer_text *text; 571 struct buffer_text *text;
572 572
573 /* Next buffer, in chain of all buffers, including killed ones. */
574 struct buffer *next;
575
576 /* Char position of point in buffer. */ 573 /* Char position of point in buffer. */
577 ptrdiff_t pt; 574 ptrdiff_t pt;
578 575
@@ -1104,15 +1101,6 @@ BUFFER_CHECK_INDIRECTION (struct buffer *b)
1104 } 1101 }
1105} 1102}
1106 1103
1107/* Chain of all buffers, including killed ones. */
1108
1109extern struct buffer *all_buffers;
1110
1111/* Used to iterate over the chain above. */
1112
1113#define FOR_EACH_BUFFER(b) \
1114 for ((b) = all_buffers; (b); (b) = (b)->next)
1115
1116/* This structure holds the default values of the buffer-local variables 1104/* This structure holds the default values of the buffer-local variables
1117 that have special slots in each buffer. 1105 that have special slots in each buffer.
1118 The default value occupies the same slot in this structure 1106 The default value occupies the same slot in this structure
diff --git a/src/pdumper.c b/src/pdumper.c
index e52163cdae2..b5861950c92 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2845,8 +2845,6 @@ dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
2845 ctx->obj_offset + dump_offsetof (struct buffer, text), 2845 ctx->obj_offset + dump_offsetof (struct buffer, text),
2846 base_offset + dump_offsetof (struct buffer, own_text)); 2846 base_offset + dump_offsetof (struct buffer, own_text));
2847 2847
2848 dump_field_lv_rawptr (ctx, out, buffer, &buffer->next,
2849 Lisp_Vectorlike, WEIGHT_NORMAL);
2850 DUMP_FIELD_COPY (out, buffer, pt); 2848 DUMP_FIELD_COPY (out, buffer, pt);
2851 DUMP_FIELD_COPY (out, buffer, pt_byte); 2849 DUMP_FIELD_COPY (out, buffer, pt_byte);
2852 DUMP_FIELD_COPY (out, buffer, begv); 2850 DUMP_FIELD_COPY (out, buffer, begv);