emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r109170: Add indirection counting to


From: Dmitry Antipov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109170: Add indirection counting to speed up Fkill_buffer.
Date: Fri, 20 Jul 2012 20:05:47 +0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109170
committer: Dmitry Antipov <address@hidden>
branch nick: trunk
timestamp: Fri 2012-07-20 20:05:47 +0400
message:
  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.
modified:
  src/ChangeLog
  src/buffer.c
  src/buffer.h
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-07-20 14:07:28 +0000
+++ b/src/ChangeLog     2012-07-20 16:05:47 +0000
@@ -1,5 +1,16 @@
 2012-07-20  Dmitry Antipov  <address@hidden>
 
+       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.
+
+2012-07-20  Dmitry Antipov  <address@hidden>
+
        Extend the value returned by Fgarbage_collect with heap statistics.
        * alloc.c (Qheap): New symbol.
        (syms_of_alloc): DEFSYM it.

=== modified file 'src/buffer.c'
--- a/src/buffer.c      2012-07-20 14:07:28 +0000
+++ b/src/buffer.c      2012-07-20 16:05:47 +0000
@@ -329,7 +329,9 @@
 
   /* 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 @@
 
   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 @@
 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 @@
   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;
 

=== modified file 'src/buffer.h'
--- a/src/buffer.h      2012-07-19 22:35:58 +0000
+++ b/src/buffer.h      2012-07-20 16:05:47 +0000
@@ -775,6 +775,11 @@
      In an ordinary buffer, it is 0.  */
   struct buffer *base_buffer;
 
+  /* In an indirect buffer, this is -1. In an ordinary buffer,
+     it's the number of indirect buffers which shares our text;
+     zero means that we're the only owner of this text.  */
+  int indirections;
+
   /* A non-zero value in slot IDX means that per-buffer variable
      with index IDX has a local value in this buffer.  The index IDX
      for a buffer-local variable is stored in that variable's slot


reply via email to

[Prev in Thread] Current Thread [Next in Thread]