emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r108836: Cleanup basic buffer managem


From: Dmitry Antipov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r108836: Cleanup basic buffer management.
Date: Tue, 03 Jul 2012 07:57:52 +0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 108836
committer: Dmitry Antipov <address@hidden>
branch nick: trunk
timestamp: Tue 2012-07-03 07:57:52 +0400
message:
  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.
modified:
  src/ChangeLog
  src/alloc.c
  src/buffer.c
  src/buffer.h
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-07-02 10:08:41 +0000
+++ b/src/ChangeLog     2012-07-03 03:57:52 +0000
@@ -1,3 +1,23 @@
+2012-07-03  Dmitry Antipov  <address@hidden>
+
+       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.
+
 2012-07-02  Paul Eggert  <address@hidden>
 
        * alloc.c (mark_object): Remove "#ifdef GC_CHECK_MARKED_OBJECTS"

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2012-07-02 07:36:17 +0000
+++ b/src/alloc.c       2012-07-03 03:57:52 +0000
@@ -1186,21 +1186,6 @@
   MALLOC_UNBLOCK_INPUT;
 }
 
-/* Return a new buffer structure allocated from the heap with
-   a call to lisp_malloc.  */
-
-struct buffer *
-allocate_buffer (void)
-{
-  struct buffer *b
-    = (struct buffer *) lisp_malloc (sizeof (struct buffer),
-                                    MEM_TYPE_BUFFER);
-  XSETPVECTYPESIZE (b, PVEC_BUFFER,
-                   ((sizeof (struct buffer) + sizeof (EMACS_INT) - 1)
-                    / sizeof (EMACS_INT)));
-  return b;
-}
-
 
 #ifndef SYSTEM_MALLOC
 
@@ -3258,6 +3243,17 @@
   return v;
 }
 
+struct buffer *
+allocate_buffer (void)
+{
+  struct buffer *b = lisp_malloc (sizeof (struct buffer), MEM_TYPE_BUFFER);
+
+  XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text)
+                                    - header_size) / word_size);
+  /* Note that the fields of B are not initialized.  */
+  return b;
+}
+
 struct Lisp_Hash_Table *
 allocate_hash_table (void)
 {
@@ -5786,15 +5782,29 @@
     }
 }
 
-/* Mark the pointers in a buffer structure.  */
+/* Mark the chain of overlays starting at PTR.  */
+
+static void
+mark_overlay (struct Lisp_Overlay *ptr)
+{
+  for (; ptr && !ptr->gcmarkbit; ptr = ptr->next)
+    {
+      ptr->gcmarkbit = 1;
+      mark_object (ptr->start);
+      mark_object (ptr->end);
+      mark_object (ptr->plist);
+    }
+}
+
+/* Mark Lisp_Objects and special pointers in BUFFER.  */
 
 static void
 mark_buffer (struct buffer *buffer)
 {
-  register Lisp_Object *ptr, tmp;
+  /* This is handled much like other pseudovectors...  */
+  mark_vectorlike ((struct Lisp_Vector *) buffer);
 
-  eassert (!VECTOR_MARKED_P (buffer));
-  VECTOR_MARK (buffer);
+  /* ...but there are some buffer-specific things.  */
 
   MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
 
@@ -5802,24 +5812,8 @@
      a special way just before the sweep phase, and after stripping
      some of its elements that are not needed any more.  */
 
-  if (buffer->overlays_before)
-    {
-      XSETMISC (tmp, buffer->overlays_before);
-      mark_object (tmp);
-    }
-  if (buffer->overlays_after)
-    {
-      XSETMISC (tmp, buffer->overlays_after);
-      mark_object (tmp);
-    }
-
-  /* buffer-local Lisp variables start at `undo_list',
-     tho only the ones from `name' on are GC'd normally.  */
-  for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name);
-       ptr <= &PER_BUFFER_VALUE (buffer,
-                                PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER));
-       ptr++)
-    mark_object (*ptr);
+  mark_overlay (buffer->overlays_before);
+  mark_overlay (buffer->overlays_after);
 
   /* If this is an indirect buffer, mark its base buffer.  */
   if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer))
@@ -6061,52 +6055,35 @@
 
     case Lisp_Misc:
       CHECK_ALLOCATED_AND_LIVE (live_misc_p);
-      if (XMISCANY (obj)->gcmarkbit)
-       break;
-      XMISCANY (obj)->gcmarkbit = 1;
 
-      switch (XMISCTYPE (obj))
+      if (XMISCTYPE (obj) == Lisp_Misc_Overlay)
+       mark_overlay (XOVERLAY (obj));
+      else
        {
-
-       case Lisp_Misc_Marker:
-         /* DO NOT mark thru the marker's chain.
-            The buffer's markers chain does not preserve markers from gc;
-            instead, markers are removed from the chain when freed by gc.  */
-         break;
-
-       case Lisp_Misc_Save_Value:
+         if (XMISCANY (obj)->gcmarkbit)
+           break;
+         XMISCANY (obj)->gcmarkbit = 1;
+
+         /* Note that we don't mark thru the marker's
+            chain.  The buffer's markers chain does not
+            preserve markers from GC; instead, markers
+            are removed from the chain when freed by GC.  */
+
 #if GC_MARK_STACK
-         {
-           register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
-           /* If DOGC is set, POINTER is the address of a memory
-              area containing INTEGER potential Lisp_Objects.  */
-           if (ptr->dogc)
-             {
-               Lisp_Object *p = (Lisp_Object *) ptr->pointer;
-               ptrdiff_t nelt;
-               for (nelt = ptr->integer; nelt > 0; nelt--, p++)
-                 mark_maybe_object (*p);
-             }
-         }
+         if (XMISCTYPE (obj) == Lisp_Misc_Save_Value)
+           {
+             register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
+             /* If DOGC is set, POINTER is the address of a memory
+                area containing INTEGER potential Lisp_Objects.  */
+             if (ptr->dogc)
+               {
+                 Lisp_Object *p = (Lisp_Object *) ptr->pointer;
+                 ptrdiff_t nelt;
+                 for (nelt = ptr->integer; nelt > 0; nelt--, p++)
+                   mark_maybe_object (*p);
+               }
+           }
 #endif
-         break;
-
-       case Lisp_Misc_Overlay:
-         {
-           struct Lisp_Overlay *ptr = XOVERLAY (obj);
-           mark_object (ptr->start);
-           mark_object (ptr->end);
-           mark_object (ptr->plist);
-           if (ptr->next)
-             {
-               XSETMISC (obj, ptr->next);
-               goto loop;
-             }
-         }
-         break;
-
-       default:
-         abort ();
        }
       break;
 

=== modified file 'src/buffer.c'
--- a/src/buffer.c      2012-06-22 21:17:42 +0000
+++ b/src/buffer.c      2012-07-03 03:57:52 +0000
@@ -465,11 +465,7 @@
 
   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 @@
     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 @@
   {
     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 @@
   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 @@
   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 @@
 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.

=== modified file 'src/buffer.h'
--- a/src/buffer.h      2012-06-24 17:39:14 +0000
+++ b/src/buffer.h      2012-07-03 03:57:52 +0000
@@ -482,142 +482,26 @@
 
 struct buffer
 {
-  /* Everything before the `name' slot must be of a non-Lisp_Object type,
-     and every slot after `name' must be a Lisp_Object.
-
-     Check out mark_buffer (alloc.c) to see why.  */
-
-  /* HEADER.NEXT is the next buffer, in chain of all buffers,
-     including killed buffers.
-     This chain is used only for garbage collection, in order to
-     collect killed buffers properly.
-     Note that vectors and most pseudovectors are all on one chain,
-     but buffers are on a separate chain of their own.  */
+  /* HEADER.NEXT is the next buffer, in chain of all buffers, including killed
+     buffers.  This chain, starting from all_buffers, is used only for garbage
+     collection, in order to collect killed buffers properly.  Note that large
+     vectors and large pseudo-vector objects are all on another chain starting
+     from large_vectors.  */
   struct vectorlike_header header;
 
-  /* This structure holds the coordinates of the buffer contents
-     in ordinary buffers.  In indirect buffers, this is not used.  */
-  struct buffer_text own_text;
-
-  /* This points to the `struct buffer_text' that used for this buffer.
-     In an ordinary buffer, this is the own_text field above.
-     In an indirect buffer, this is the own_text field of another buffer.  */
-  struct buffer_text *text;
-
-  /* Char position of point in buffer.  */
-  ptrdiff_t pt;
-  /* Byte position of point in buffer.  */
-  ptrdiff_t pt_byte;
-  /* Char position of beginning of accessible range.  */
-  ptrdiff_t begv;
-  /* Byte position of beginning of accessible range.  */
-  ptrdiff_t begv_byte;
-  /* Char position of end of accessible range.  */
-  ptrdiff_t zv;
-  /* Byte position of end of accessible range.  */
-  ptrdiff_t zv_byte;
-
-  /* In an indirect buffer, this points to the base buffer.
-     In an ordinary buffer, it is 0.  */
-  struct buffer *base_buffer;
-
-  /* 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
-     in buffer_local_flags as a Lisp integer.  If the index is -1,
-     this means the variable is always local in all buffers.  */
-#define MAX_PER_BUFFER_VARS 50
-  char local_flags[MAX_PER_BUFFER_VARS];
-
-  /* Set to the modtime of the visited file when read or written.
-     EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means
-     visited file was nonexistent.  EMACS_NSECS (modtime) ==
-     UNKNOWN_MODTIME_NSECS means visited file modtime unknown;
-     in no case complain about any mismatch on next save attempt.  */
-#define NONEXISTENT_MODTIME_NSECS (-1)
-#define UNKNOWN_MODTIME_NSECS (-2)
-  EMACS_TIME modtime;
-  /* Size of the file when modtime was set.  This is used to detect the
-     case where the file grew while we were reading it, so the modtime
-     is still the same (since it's rounded up to seconds) but we're actually
-     not up-to-date.  -1 means the size is unknown.  Only meaningful if
-     modtime is actually set.  */
-  off_t modtime_size;
-  /* The value of text->modiff at the last auto-save.  */
-  EMACS_INT auto_save_modified;
-  /* The value of text->modiff at the last display error.
-     Redisplay of this buffer is inhibited until it changes again.  */
-  EMACS_INT display_error_modiff;
-  /* The time at which we detected a failure to auto-save,
-     Or 0 if we didn't have a failure.  */
-  time_t auto_save_failure_time;
-  /* Position in buffer at which display started
-     the last time this buffer was displayed.  */
-  ptrdiff_t last_window_start;
-
-  /* Set nonzero whenever the narrowing is changed in this buffer.  */
-  int clip_changed;
-
-  /* If the long line scan cache is enabled (i.e. the buffer-local
-     variable cache-long-line-scans is non-nil), newline_cache
-     points to the newline cache, and width_run_cache points to the
-     width run cache.
-
-     The newline cache records which stretches of the buffer are
-     known *not* to contain newlines, so that they can be skipped
-     quickly when we search for newlines.
-
-     The width run cache records which stretches of the buffer are
-     known to contain characters whose widths are all the same.  If
-     the width run cache maps a character to a value > 0, that value is
-     the character's width; if it maps a character to zero, we don't
-     know what its width is.  This allows compute_motion to process
-     such regions very quickly, using algebra instead of inspecting
-     each character.   See also width_table, below.  */
-  struct region_cache *newline_cache;
-  struct region_cache *width_run_cache;
-
-  /* Non-zero means don't use redisplay optimizations for
-     displaying this buffer.  */
-  unsigned prevent_redisplay_optimizations_p : 1;
-
-  /* List of overlays that end at or before the current center,
-     in order of end-position.  */
-  struct Lisp_Overlay *overlays_before;
-
-  /* List of overlays that end after  the current center,
-     in order of start-position.  */
-  struct Lisp_Overlay *overlays_after;
-
-  /* Position where the overlay lists are centered.  */
-  ptrdiff_t overlay_center;
-
-  /* Everything from here down must be a Lisp_Object.  */
-  /* buffer-local Lisp variables start at `undo_list',
-     tho only the ones from `name' on are GC'd normally.  */
-  #define FIRST_FIELD_PER_BUFFER undo_list
-
-  /* Changes in the buffer are recorded here for undo.
-     t means don't record anything.
-     This information belongs to the base buffer of an indirect buffer,
-     But we can't store it in the  struct buffer_text
-     because local variables have to be right in the  struct buffer.
-     So we copy it around in set_buffer_internal.
-     This comes before `name' because it is marked in a special way.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (undo_list);
-
   /* The name of this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (name);
 
   /* The name of the file visited in this buffer, or nil.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (filename);
-  /* Dir for expanding relative file names.  */
+
+  /* Directory for expanding relative file names.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (directory);
-  /* True if this buffer has been backed up (if you write to the
-     visited file and it hasn't been backed up, then a backup will
-     be made).  */
-  /* This isn't really used by the C code, so could be deleted.  */
+
+  /* True if this buffer has been backed up (if you write to the visited
+     file and it hasn't been backed up, then a backup will be made).  */
   Lisp_Object BUFFER_INTERNAL_FIELD (backed_up);
+
   /* Length of file when last read or saved.
      -1 means auto saving turned off because buffer shrank a lot.
      -2 means don't turn off auto saving if buffer shrinks.
@@ -625,6 +509,7 @@
      This is not in the  struct buffer_text
      because it's not used in indirect buffers at all.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (save_length);
+
   /* File name used for auto-saving this buffer.
      This is not in the  struct buffer_text
      because it's not used in indirect buffers at all.  */
@@ -632,6 +517,7 @@
 
   /* Non-nil if buffer read-only.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (read_only);
+
   /* "The mark".  This is a marker which may
      point into this buffer or may point nowhere.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (mark);
@@ -641,10 +527,12 @@
      symbols, just the symbol appears as the element.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (local_var_alist);
 
-  /* Symbol naming major mode (eg, lisp-mode).  */
+  /* Symbol naming major mode (e.g., lisp-mode).  */
   Lisp_Object BUFFER_INTERNAL_FIELD (major_mode);
-  /* Pretty name of major mode (eg, "Lisp"). */
+
+  /* Pretty name of major mode (e.g., "Lisp"). */
   Lisp_Object BUFFER_INTERNAL_FIELD (mode_name);
+
   /* Mode line element that controls format of mode line.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (mode_line_format);
 
@@ -654,10 +542,13 @@
 
   /* Keys that are bound local to this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (keymap);
+
   /* This buffer's local abbrev table.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (abbrev_table);
+
   /* This buffer's syntax table.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (syntax_table);
+
   /* This buffer's category table.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (category_table);
 
@@ -668,48 +559,61 @@
   Lisp_Object BUFFER_INTERNAL_FIELD (tab_width);
   Lisp_Object BUFFER_INTERNAL_FIELD (fill_column);
   Lisp_Object BUFFER_INTERNAL_FIELD (left_margin);
+
   /* Function to call when insert space past fill column.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (auto_fill_function);
 
   /* Case table for case-conversion in this buffer.
      This char-table maps each char into its lower-case version.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (downcase_table);
+
   /* Char-table mapping each char to its upper-case version.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (upcase_table);
+
   /* Char-table for conversion for case-folding search.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (case_canon_table);
+
   /* Char-table of equivalences for case-folding search.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (case_eqv_table);
 
   /* Non-nil means do not display continuation lines.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (truncate_lines);
+
   /* Non-nil means to use word wrapping when displaying continuation lines.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (word_wrap);
+
   /* Non-nil means display ctl chars with uparrow.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (ctl_arrow);
+
   /* Non-nil means reorder bidirectional text for display in the
      visual order.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (bidi_display_reordering);
+
   /* If non-nil, specifies which direction of text to force in all the
      paragraphs of the buffer.  Nil means determine paragraph
      direction dynamically for each paragraph.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (bidi_paragraph_direction);
+
   /* Non-nil means do selective display;
      see doc string in syms_of_buffer (buffer.c) for details.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (selective_display);
-#ifndef old
+
   /* Non-nil means show ... at end of line followed by invisible lines.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (selective_display_ellipses);
-#endif
+
   /* Alist of (FUNCTION . STRING) for each minor mode enabled in buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (minor_modes);
+
   /* t if "self-insertion" should overwrite; `binary' if it should also
      overwrite newlines and tabs - for editing executables and the like.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (overwrite_mode);
-  /* non-nil means abbrev mode is on.  Expand abbrevs automatically.  */
+
+  /* Non-nil means abbrev mode is on.  Expand abbrevs automatically.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (abbrev_mode);
+
   /* Display table to use for text in this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (display_table);
+
   /* t means the mark and region are currently active.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (mark_active);
 
@@ -776,11 +680,13 @@
 
   /* Widths of left and right marginal areas for windows displaying
      this buffer.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (left_margin_cols), BUFFER_INTERNAL_FIELD 
(right_margin_cols);
+  Lisp_Object BUFFER_INTERNAL_FIELD (left_margin_cols);
+  Lisp_Object BUFFER_INTERNAL_FIELD (right_margin_cols);
 
   /* Widths of left and right fringe areas for windows displaying
      this buffer.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (left_fringe_width), BUFFER_INTERNAL_FIELD 
(right_fringe_width);
+  Lisp_Object BUFFER_INTERNAL_FIELD (left_fringe_width);
+  Lisp_Object BUFFER_INTERNAL_FIELD (right_fringe_width);
 
   /* Non-nil means fringes are drawn outside display margins;
      othersize draw them between margin areas and text.  */
@@ -788,7 +694,8 @@
 
   /* Width and type of scroll bar areas for windows displaying
      this buffer.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (scroll_bar_width), BUFFER_INTERNAL_FIELD 
(vertical_scroll_bar_type);
+  Lisp_Object BUFFER_INTERNAL_FIELD (scroll_bar_width);
+  Lisp_Object BUFFER_INTERNAL_FIELD (vertical_scroll_bar_type);
 
   /* Non-nil means indicate lines not displaying text (in a style
      like vi).  */
@@ -826,13 +733,127 @@
      in the display of this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (extra_line_spacing);
 
-  /* *Cursor type to display in non-selected windows.
+  /* Cursor type to display in non-selected windows.
      t means to use hollow box cursor.
      See `cursor-type' for other values.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows);
 
-  /* This must be the last field in the above list.  */
-  #define LAST_FIELD_PER_BUFFER cursor_in_non_selected_windows
+  /* No more Lisp_Object beyond this point.  Except undo_list,
+     which is handled specially in Fgarbage_collect .  */
+
+  /* This structure holds the coordinates of the buffer contents
+     in ordinary buffers.  In indirect buffers, this is not used.  */
+  struct buffer_text own_text;
+
+  /* This points to the `struct buffer_text' that used for this buffer.
+     In an ordinary buffer, this is the own_text field above.
+     In an indirect buffer, this is the own_text field of another buffer.  */
+  struct buffer_text *text;
+
+  /* Char position of point in buffer.  */
+  ptrdiff_t pt;
+
+  /* Byte position of point in buffer.  */
+  ptrdiff_t pt_byte;
+
+  /* Char position of beginning of accessible range.  */
+  ptrdiff_t begv;
+
+  /* Byte position of beginning of accessible range.  */
+  ptrdiff_t begv_byte;
+
+  /* Char position of end of accessible range.  */
+  ptrdiff_t zv;
+
+  /* Byte position of end of accessible range.  */
+  ptrdiff_t zv_byte;
+
+  /* In an indirect buffer, this points to the base buffer.
+     In an ordinary buffer, it is 0.  */
+  struct buffer *base_buffer;
+
+  /* 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
+     in buffer_local_flags as a Lisp integer.  If the index is -1,
+     this means the variable is always local in all buffers.  */
+#define MAX_PER_BUFFER_VARS 50
+  char local_flags[MAX_PER_BUFFER_VARS];
+
+  /* Set to the modtime of the visited file when read or written.
+     EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means
+     visited file was nonexistent.  EMACS_NSECS (modtime) ==
+     UNKNOWN_MODTIME_NSECS means visited file modtime unknown;
+     in no case complain about any mismatch on next save attempt.  */
+#define NONEXISTENT_MODTIME_NSECS (-1)
+#define UNKNOWN_MODTIME_NSECS (-2)
+  EMACS_TIME modtime;
+
+  /* Size of the file when modtime was set.  This is used to detect the
+     case where the file grew while we were reading it, so the modtime
+     is still the same (since it's rounded up to seconds) but we're actually
+     not up-to-date.  -1 means the size is unknown.  Only meaningful if
+     modtime is actually set.  */
+  off_t modtime_size;
+
+  /* The value of text->modiff at the last auto-save.  */
+  EMACS_INT auto_save_modified;
+
+  /* The value of text->modiff at the last display error.
+     Redisplay of this buffer is inhibited until it changes again.  */
+  EMACS_INT display_error_modiff;
+
+  /* The time at which we detected a failure to auto-save,
+     Or 0 if we didn't have a failure.  */
+  time_t auto_save_failure_time;
+
+  /* Position in buffer at which display started
+     the last time this buffer was displayed.  */
+  ptrdiff_t last_window_start;
+
+  /* If the long line scan cache is enabled (i.e. the buffer-local
+     variable cache-long-line-scans is non-nil), newline_cache
+     points to the newline cache, and width_run_cache points to the
+     width run cache.
+
+     The newline cache records which stretches of the buffer are
+     known *not* to contain newlines, so that they can be skipped
+     quickly when we search for newlines.
+
+     The width run cache records which stretches of the buffer are
+     known to contain characters whose widths are all the same.  If
+     the width run cache maps a character to a value > 0, that value is
+     the character's width; if it maps a character to zero, we don't
+     know what its width is.  This allows compute_motion to process
+     such regions very quickly, using algebra instead of inspecting
+     each character.   See also width_table, below.  */
+  struct region_cache *newline_cache;
+  struct region_cache *width_run_cache;
+
+  /* Non-zero means don't use redisplay optimizations for
+     displaying this buffer.  */
+  unsigned prevent_redisplay_optimizations_p : 1;
+
+  /* Non-zero whenever the narrowing is changed in this buffer.  */
+  unsigned clip_changed : 1;
+
+  /* List of overlays that end at or before the current center,
+     in order of end-position.  */
+  struct Lisp_Overlay *overlays_before;
+
+  /* List of overlays that end after  the current center,
+     in order of start-position.  */
+  struct Lisp_Overlay *overlays_after;
+
+  /* Position where the overlay lists are centered.  */
+  ptrdiff_t overlay_center;
+
+  /* Changes in the buffer are recorded here for undo, and t means
+     don't record anything.  This information belongs to the base
+     buffer of an indirect buffer.  But we can't store it in the
+     struct buffer_text because local variables have to be right in
+     the struct buffer. So we copy it around in set_buffer_internal.  */
+  Lisp_Object BUFFER_INTERNAL_FIELD (undo_list);
 };
 
 
@@ -896,10 +917,10 @@
 
 #define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq)                
\
   do {                                                                 \
-    ptrdiff_t maxlen = 40;                                                     
\
+    ptrdiff_t maxlen = 40;                                             \
     overlays = (Lisp_Object *) alloca (maxlen * sizeof (Lisp_Object)); \
     noverlays = overlays_at (posn, 0, &overlays, &maxlen,              \
-                            nextp, NULL, chrq);                                
\
+                            nextp, NULL, chrq);                        \
     if (noverlays > maxlen)                                            \
       {                                                                        
\
        maxlen = noverlays;                                             \
@@ -992,6 +1013,15 @@
 #define PER_BUFFER_VAR_OFFSET(VAR) \
   offsetof (struct buffer, BUFFER_INTERNAL_FIELD (VAR))
 
+/* Used to iterate over normal Lisp_Object fields of struct buffer (all
+   Lisp_Objects except undo_list).  If you add, remove, or reorder
+   Lisp_Objects in a struct buffer, make sure that this is still correct.  */
+
+#define for_each_per_buffer_object_at(offset)                           \
+  for (offset = PER_BUFFER_VAR_OFFSET (name);                           \
+       offset <= PER_BUFFER_VAR_OFFSET (cursor_in_non_selected_windows); \
+       offset += sizeof (Lisp_Object))
+
 /* Return the index of buffer-local variable VAR.  Each per-buffer
    variable has an index > 0 associated with it, except when it always
    has buffer-local values, in which case the index is -1.  If this is


reply via email to

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