aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2012-07-20 20:05:47 +0400
committerDmitry Antipov2012-07-20 20:05:47 +0400
commit9928463dcdb0164477785e83406602065de79ef8 (patch)
tree14d6b28885b7e333733ff4eb62275e6e425f81b3 /src
parentf8643a6b9e35af22b69a84f83df5d9410de82f16 (diff)
downloademacs-9928463dcdb0164477785e83406602065de79ef8.tar.gz
emacs-9928463dcdb0164477785e83406602065de79ef8.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/buffer.c32
-rw-r--r--src/buffer.h5
3 files changed, 45 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d7d02a2262a..e90e48ee9dc 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,16 @@
12012-07-20 Dmitry Antipov <dmantipov@yandex.ru> 12012-07-20 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 Add indirection counting to speed up Fkill_buffer.
4 * buffer.h (struct buffer): New member.
5 * buffer.c (Fget_buffer_create): Set indirection counter to 0.
6 (Fmake_indirect_buffer): Set indirection counter to -1, increment
7 base buffer indirection counter.
8 (compact_buffer): If ENABLE_CHECKING, verify indirection counters.
9 (Fkill_buffer): Adjust indirection counters as needed, don't walk
10 through buffer list if indirection counter is 0.
11
122012-07-20 Dmitry Antipov <dmantipov@yandex.ru>
13
3 Extend the value returned by Fgarbage_collect with heap statistics. 14 Extend the value returned by Fgarbage_collect with heap statistics.
4 * alloc.c (Qheap): New symbol. 15 * alloc.c (Qheap): New symbol.
5 (syms_of_alloc): DEFSYM it. 16 (syms_of_alloc): DEFSYM it.
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. */)
329 329
330 /* An ordinary buffer uses its own struct buffer_text. */ 330 /* An ordinary buffer uses its own struct buffer_text. */
331 b->text = &b->own_text; 331 b->text = &b->own_text;
332 b->base_buffer = 0; 332 b->base_buffer = NULL;
333 /* No one shares the text with us now. */
334 b->indirections = 0;
333 335
334 BUF_GAP_SIZE (b) = 20; 336 BUF_GAP_SIZE (b) = 20;
335 BLOCK_INPUT; 337 BLOCK_INPUT;
@@ -568,12 +570,18 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
568 570
569 b = allocate_buffer (); 571 b = allocate_buffer ();
570 572
573 /* No double indirection - if base buffer is indirect,
574 new buffer becomes an indirect to base's base. */
571 b->base_buffer = (XBUFFER (base_buffer)->base_buffer 575 b->base_buffer = (XBUFFER (base_buffer)->base_buffer
572 ? XBUFFER (base_buffer)->base_buffer 576 ? XBUFFER (base_buffer)->base_buffer
573 : XBUFFER (base_buffer)); 577 : XBUFFER (base_buffer));
574 578
575 /* Use the base buffer's text object. */ 579 /* Use the base buffer's text object. */
576 b->text = b->base_buffer->text; 580 b->text = b->base_buffer->text;
581 /* We have no own text. */
582 b->indirections = -1;
583 /* Notify base buffer that we share the text now. */
584 b->base_buffer->indirections++;
577 585
578 b->pt = b->base_buffer->pt; 586 b->pt = b->base_buffer->pt;
579 b->begv = b->base_buffer->begv; 587 b->begv = b->base_buffer->begv;
@@ -1439,6 +1447,15 @@ No argument or nil as argument means do this for the current buffer. */)
1439int 1447int
1440compact_buffer (struct buffer *buffer) 1448compact_buffer (struct buffer *buffer)
1441{ 1449{
1450 /* Verify indirection counters. */
1451 if (buffer->base_buffer)
1452 {
1453 eassert (buffer->indirections == -1);
1454 eassert (buffer->base_buffer->indirections > 0);
1455 }
1456 else
1457 eassert (buffer->indirections >= 0);
1458
1442 /* Skip dead buffers, indirect buffers and buffers 1459 /* Skip dead buffers, indirect buffers and buffers
1443 which aren't changed since last compaction. */ 1460 which aren't changed since last compaction. */
1444 if (!NILP (buffer->BUFFER_INTERNAL_FIELD (name)) 1461 if (!NILP (buffer->BUFFER_INTERNAL_FIELD (name))
@@ -1555,10 +1572,19 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1555 if (EQ (buffer, XWINDOW (minibuf_window)->buffer)) 1572 if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
1556 return Qnil; 1573 return Qnil;
1557 1574
1558 /* When we kill a base buffer, kill all its indirect buffers. 1575 /* Notify our base buffer that we don't share the text anymore. */
1576 if (b->base_buffer)
1577 {
1578 eassert (b->indirections == -1);
1579 b->base_buffer->indirections--;
1580 eassert (b->base_buffer->indirections >= 0);
1581 }
1582
1583 /* When we kill an ordinary buffer which shares it's buffer text
1584 with indirect buffer(s), we must kill indirect buffer(s) too.
1559 We do it at this stage so nothing terrible happens if they 1585 We do it at this stage so nothing terrible happens if they
1560 ask questions or their hooks get errors. */ 1586 ask questions or their hooks get errors. */
1561 if (! b->base_buffer) 1587 if (!b->base_buffer && b->indirections > 0)
1562 { 1588 {
1563 struct buffer *other; 1589 struct buffer *other;
1564 1590
diff --git a/src/buffer.h b/src/buffer.h
index a97cc13705b..69be4dc7773 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -775,6 +775,11 @@ struct buffer
775 In an ordinary buffer, it is 0. */ 775 In an ordinary buffer, it is 0. */
776 struct buffer *base_buffer; 776 struct buffer *base_buffer;
777 777
778 /* In an indirect buffer, this is -1. In an ordinary buffer,
779 it's the number of indirect buffers which shares our text;
780 zero means that we're the only owner of this text. */
781 int indirections;
782
778 /* A non-zero value in slot IDX means that per-buffer variable 783 /* A non-zero value in slot IDX means that per-buffer variable
779 with index IDX has a local value in this buffer. The index IDX 784 with index IDX has a local value in this buffer. The index IDX
780 for a buffer-local variable is stored in that variable's slot 785 for a buffer-local variable is stored in that variable's slot