* alloc.c (pure_bytes_used_lisp, pure_bytes_used_non_lisp):
[bpt/emacs.git] / src / buffer.c
index 8fdd094..564dab6 100644 (file)
@@ -27,6 +27,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <setjmp.h>
 #include <unistd.h>
 
+#include <verify.h>
+
 #include "lisp.h"
 #include "intervals.h"
 #include "window.h"
@@ -92,6 +94,11 @@ static Lisp_Object Vbuffer_local_symbols;
 #define PER_BUFFER_SYMBOL(OFFSET) \
       (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols))
 
+/* Maximum length of an overlay vector.  */
+#define OVERLAY_COUNT_MAX                                              \
+  ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM,                              \
+                   min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)))
+
 /* Flags indicating which built-in buffer-local variables
    are permanent locals.  */
 static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
@@ -131,22 +138,24 @@ static Lisp_Object Qprotected_field;
 static Lisp_Object QSFundamental;      /* A string "Fundamental" */
 
 static Lisp_Object Qkill_buffer_hook;
+static Lisp_Object Qbuffer_list_update_hook;
 
 static Lisp_Object Qget_file_buffer;
 
 static Lisp_Object Qoverlayp;
 
 Lisp_Object Qpriority, Qbefore_string, Qafter_string;
+
 static Lisp_Object Qevaporate;
 
 Lisp_Object Qmodification_hooks;
 Lisp_Object Qinsert_in_front_hooks;
 Lisp_Object Qinsert_behind_hooks;
 
-static void alloc_buffer_text (struct buffer *, size_t);
+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 void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
 static Lisp_Object buffer_lisp_local_variables (struct buffer *);
 
 /* For debugging; temporary.  See set_buffer_internal.  */
@@ -171,9 +180,9 @@ Value is nil if OBJECT is not a buffer or if it has been killed.  */)
 
 DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
        doc: /* Return a list of all existing live buffers.
-If the optional arg FRAME is a frame, we return the buffer list
-in the proper order for that frame: the buffers in FRAME's `buffer-list'
-frame parameter come first, followed by the rest of the buffers.  */)
+If the optional arg FRAME is a frame, we return the buffer list in the
+proper order for that frame: the buffers show in FRAME come first,
+followed by the rest of the buffers.  */)
   (Lisp_Object frame)
 {
   Lisp_Object general;
@@ -185,9 +194,9 @@ frame parameter come first, followed by the rest of the buffers.  */)
       Lisp_Object args[3];
 
       CHECK_FRAME (frame);
-
       framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
-      prevlist = Fnreverse (Fcopy_sequence (XFRAME (frame)->buried_buffer_list));
+      prevlist = Fnreverse (Fcopy_sequence
+                           (XFRAME (frame)->buried_buffer_list));
 
       /* Remove from GENERAL any buffer that duplicates one in
          FRAMELIST or PREVLIST.  */
@@ -209,8 +218,8 @@ frame parameter come first, followed by the rest of the buffers.  */)
       args[2] = prevlist;
       return Fnconc (3, args);
     }
-
-  return general;
+  else
+    return general;
 }
 
 /* Like Fassoc, but use Fstring_equal to compare
@@ -352,6 +361,7 @@ even if it is dead.  The return value is never nil.  */)
   BUF_END_UNCHANGED (b) = 0;
   BUF_BEG_UNCHANGED (b) = 0;
   *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'.  */
+  b->text->inhibit_shrinking = 0;
 
   b->newline_cache = 0;
   b->width_run_cache = 0;
@@ -384,6 +394,9 @@ even if it is dead.  The return value is never nil.  */)
   /* Put this in the alist of all live buffers.  */
   XSETBUFFER (buffer, b);
   Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil));
+  /* And run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
 
   /* An error in calling the function here (should someone redefine it)
      can lead to infinite regress until you run out of stack.  rms
@@ -410,7 +423,7 @@ copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
   for (; list; list = list->next)
     {
       Lisp_Object overlay, start, end, old_overlay;
-      EMACS_INT charpos;
+      ptrdiff_t charpos;
 
       XSETMISC (old_overlay, list);
       charpos = marker_position (OVERLAY_START (old_overlay));
@@ -459,8 +472,8 @@ clone_per_buffer_values (struct buffer *from, struct 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 (undo_list);
-       offset < sizeof *to;
+  for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
+       offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
        offset += sizeof (Lisp_Object))
     {
       Lisp_Object obj;
@@ -659,6 +672,10 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
       set_buffer_internal_1 (old_b);
     }
 
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
   return buf;
 }
 
@@ -707,7 +724,7 @@ reset_buffer (register struct buffer *b)
   b->prevent_redisplay_optimizations_p = 1;
   BVAR (b, backed_up) = Qnil;
   BUF_AUTOSAVE_MODIFF (b) = 0;
-  b->auto_save_failure_time = -1;
+  b->auto_save_failure_time = 0;
   BVAR (b, auto_save_file_name) = Qnil;
   BVAR (b, read_only) = Qnil;
   b->overlays_before = NULL;
@@ -814,8 +831,8 @@ reset_buffer_local_variables (register struct buffer *b, int permanent_too)
 
   /* 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 (undo_list);
-       offset < sizeof *b;
+  for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
+       offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
        offset += sizeof (Lisp_Object))
     {
       int idx = PER_BUFFER_IDX (offset);
@@ -841,8 +858,8 @@ it is in the sequence to be tried) even if a buffer with that name exists.  */)
   (register Lisp_Object name, Lisp_Object ignore)
 {
   register Lisp_Object gentemp, tem;
-  EMACS_INT count;
-  char number[INT_BUFSIZE_BOUND (EMACS_INT) + sizeof "<>"];
+  ptrdiff_t count;
+  char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"];
 
   CHECK_STRING (name);
 
@@ -856,7 +873,7 @@ it is in the sequence to be tried) even if a buffer with that name exists.  */)
   count = 1;
   while (1)
     {
-      sprintf (number, "<%"pI"d>", ++count);
+      sprintf (number, "<%"pD"d>", ++count);
       gentemp = concat2 (name, build_string (number));
       tem = Fstring_equal (gentemp, ignore);
       if (!NILP (tem))
@@ -1039,8 +1056,8 @@ No argument or nil as argument means use current buffer as BUFFER.  */)
 
     /* 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 (undo_list);
-        offset < sizeof (struct buffer);
+    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)))
       {
@@ -1262,81 +1279,119 @@ This does not change the name of the visited file (if any).  */)
   if (NILP (BVAR (current_buffer, filename))
       && !NILP (BVAR (current_buffer, auto_save_file_name)))
     call0 (intern ("rename-auto-save-file"));
+
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
   /* Refetch since that last call may have done GC.  */
   return BVAR (current_buffer, name);
 }
 
 DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
        doc: /* Return most recently selected buffer other than BUFFER.
-Buffers not visible in windows are preferred to visible buffers,
-unless optional second argument VISIBLE-OK is non-nil.
-If the optional third argument FRAME is non-nil, use that frame's
-buffer list instead of the selected frame's buffer list.
-If no other buffer exists, the buffer `*scratch*' is returned.
-If BUFFER is omitted or nil, some interesting buffer is returned.  */)
+Buffers not visible in windows are preferred to visible buffers, unless
+optional second argument VISIBLE-OK is non-nil.  Ignore the argument
+BUFFER unless it denotes a live buffer.  If the optional third argument
+FRAME is non-nil, use that frame's buffer list instead of the selected
+frame's buffer list.
+
+The buffer is found by scanning the selected or specified frame's buffer
+list first, followed by the list of all buffers.  If no other buffer
+exists, return the buffer `*scratch*' (creating it if necessary).  */)
   (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
 {
-  register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
-  notsogood = Qnil;
+  Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
+  Lisp_Object tail, buf, pred;
+  Lisp_Object notsogood = Qnil;
 
   if (NILP (frame))
     frame = selected_frame;
 
   CHECK_FRAME (frame);
 
-  tail = Vbuffer_alist;
   pred = frame_buffer_predicate (frame);
-
-  /* Consider buffers that have been seen in the selected frame
-     before other buffers.  */
-
-  tem = frame_buffer_list (frame);
-  add_ons = Qnil;
-  while (CONSP (tem))
+  /* Consider buffers that have been seen in the frame first.  */
+  tail = XFRAME (frame)->buffer_list;
+  for (; CONSP (tail); tail = XCDR (tail))
     {
-      if (BUFFERP (XCAR (tem)))
-       add_ons = Fcons (Fcons (Qnil, XCAR (tem)), add_ons);
-      tem = XCDR (tem);
+      buf = XCAR (tail);
+      if (BUFFERP (buf) && !EQ (buf, buffer)
+         && !NILP (BVAR (XBUFFER (buf), name))
+         && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+         /* If the frame has a buffer_predicate, disregard buffers that
+            don't fit the predicate.  */
+         && (NILP (pred) || !NILP (call1 (pred, buf))))
+       {
+         if (!NILP (visible_ok)
+             || NILP (Fget_buffer_window (buf, Qvisible)))
+           return buf;
+         else if (NILP (notsogood))
+           notsogood = buf;
+       }
     }
-  tail = nconc2 (Fnreverse (add_ons), tail);
 
+  /* Consider alist of all buffers next.  */
+  tail = Vbuffer_alist;
   for (; CONSP (tail); tail = XCDR (tail))
     {
       buf = Fcdr (XCAR (tail));
-      if (EQ (buf, buffer))
-       continue;
+      if (BUFFERP (buf) && !EQ (buf, buffer)
+         && !NILP (BVAR (XBUFFER (buf), name))
+         && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+         /* If the frame has a buffer_predicate, disregard buffers that
+            don't fit the predicate.  */
+         && (NILP (pred) || !NILP (call1 (pred, buf))))
+       {
+         if (!NILP (visible_ok)
+             || NILP (Fget_buffer_window (buf, Qvisible)))
+           return buf;
+         else if (NILP (notsogood))
+           notsogood = buf;
+       }
+    }
+
+  if (!NILP (notsogood))
+    return notsogood;
+  else
+    {
+      buf = Fget_buffer (build_string ("*scratch*"));
       if (NILP (buf))
-       continue;
-      if (NILP (BVAR (XBUFFER (buf), name)))
-       continue;
-      if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
-       continue;
-      /* If the selected frame has a buffer_predicate,
-        disregard buffers that don't fit the predicate.  */
-      if (!NILP (pred))
        {
-         tem = call1 (pred, buf);
-         if (NILP (tem))
-           continue;
+         buf = Fget_buffer_create (build_string ("*scratch*"));
+         Fset_buffer_major_mode (buf);
        }
+      return buf;
+    }
+}
 
-      if (NILP (visible_ok))
-       tem = Fget_buffer_window (buf, Qvisible);
-      else
-       tem = Qnil;
-      if (NILP (tem))
+/* The following function is a safe variant of Fother_buffer: It doesn't
+   pay attention to any frame-local buffer lists, doesn't care about
+   visibility of buffers, and doesn't evaluate any frame predicates.  */
+
+Lisp_Object
+other_buffer_safely (Lisp_Object buffer)
+{
+  Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
+  Lisp_Object tail, buf;
+
+  tail = Vbuffer_alist;
+  for (; CONSP (tail); tail = XCDR (tail))
+    {
+      buf = Fcdr (XCAR (tail));
+      if (BUFFERP (buf) && !EQ (buf, buffer)
+         && !NILP (BVAR (XBUFFER (buf), name))
+         && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
        return buf;
-      if (NILP (notsogood))
-       notsogood = buf;
     }
-  if (!NILP (notsogood))
-    return notsogood;
+
   buf = Fget_buffer (build_string ("*scratch*"));
   if (NILP (buf))
     {
       buf = Fget_buffer_create (build_string ("*scratch*"));
       Fset_buffer_major_mode (buf);
     }
+
   return buf;
 }
 \f
@@ -1420,7 +1475,7 @@ with SIGHUP.  */)
 
   /* Run hooks with the buffer to be killed the current buffer.  */
   {
-    int count = SPECPDL_INDEX ();
+    ptrdiff_t count = SPECPDL_INDEX ();
     Lisp_Object arglist[1];
 
     record_unwind_protect (save_excursion_restore, save_excursion_save ());
@@ -1509,13 +1564,20 @@ with SIGHUP.  */)
   if (NILP (BVAR (b, name)))
     return Qnil;
 
+  /* These may run Lisp code and into infinite loops (if someone
+     insisted on circular lists) so allow quitting here.  */
+  replace_buffer_in_windows (buffer);
+  frames_discard_buffer (buffer);
+
   clear_charpos_cache (b);
 
   tem = Vinhibit_quit;
   Vinhibit_quit = Qt;
-  replace_buffer_in_all_windows (buffer);
+  /* Remove the buffer from the list of all buffers.  */
   Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
-  frames_discard_buffer (buffer);
+  /* If replace_buffer_in_windows didn't do its job correctly fix that
+     now.  */
+  replace_buffer_in_windows_safely (buffer);
   Vinhibit_quit = tem;
 
   /* Delete any auto-save file, if we saved it in this session.
@@ -1589,83 +1651,91 @@ with SIGHUP.  */)
   UNBLOCK_INPUT;
   BVAR (b, undo_list) = Qnil;
 
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
   return Qt;
 }
 \f
-/* Move the assoc for buffer BUF to the front of buffer-alist.  Since
-   we do this each time BUF is selected visibly, the more recently
-   selected buffers are always closer to the front of the list.  This
-   means that other_buffer is more likely to choose a relevant buffer.  */
+/* Move association for BUFFER to the front of buffer (a)lists.  Since
+   we do this each time BUFFER is selected visibly, the more recently
+   selected buffers are always closer to the front of those lists.  This
+   means that other_buffer is more likely to choose a relevant buffer.
+
+   Note that this moves BUFFER to the front of the buffer lists of the
+   selected frame even if BUFFER is not shown there.  If BUFFER is not
+   shown in the selected frame, consider the present behavior a feature.
+   `select-window' gets this right since it shows BUFFER in the selected
+   window when calling us.  */
 
 void
-record_buffer (Lisp_Object buf)
+record_buffer (Lisp_Object buffer)
 {
-  register Lisp_Object list, prev;
-  Lisp_Object frame;
-  frame = selected_frame;
+  Lisp_Object aelt, aelt_cons, tem;
+  register struct frame *f = XFRAME (selected_frame);
 
-  prev = Qnil;
-  for (list = Vbuffer_alist; CONSP (list); list = XCDR (list))
-    {
-      if (EQ (XCDR (XCAR (list)), buf))
-       break;
-      prev = list;
-    }
+  CHECK_BUFFER (buffer);
 
-  /* Effectively do Vbuffer_alist = Fdelq (list, Vbuffer_alist);
-     we cannot use Fdelq itself here because it allows quitting.  */
+  /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
+     Don't allow quitting since this might leave the buffer list in an
+     inconsistent state.  */
+  tem = Vinhibit_quit;
+  Vinhibit_quit = Qt;
+  aelt = Frassq (buffer, Vbuffer_alist);
+  aelt_cons = Fmemq (aelt, Vbuffer_alist);
+  Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+  XSETCDR (aelt_cons, Vbuffer_alist);
+  Vbuffer_alist = aelt_cons;
+  Vinhibit_quit = tem;
 
-  if (NILP (prev))
-    Vbuffer_alist = XCDR (Vbuffer_alist);
-  else
-    XSETCDR (prev, XCDR (XCDR (prev)));
+  /* Update buffer list of selected frame.  */
+  f->buffer_list = Fcons (buffer, Fdelq (buffer, f->buffer_list));
+  f->buried_buffer_list = Fdelq (buffer, f->buried_buffer_list);
 
-  XSETCDR (list, Vbuffer_alist);
-  Vbuffer_alist = list;
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+}
 
-  /* Effectively do a delq on buried_buffer_list.  */
 
-  prev = Qnil;
-  for (list = XFRAME (frame)->buried_buffer_list; CONSP (list);
-       list = XCDR (list))
-    {
-      if (EQ (XCAR (list), buf))
-        {
-          if (NILP (prev))
-            XFRAME (frame)->buried_buffer_list = XCDR (list);
-          else
-            XSETCDR (prev, XCDR (XCDR (prev)));
-          break;
-        }
-      prev = list;
-    }
+/* Move BUFFER to the end of the buffer (a)lists.  Do nothing if the
+   buffer is killed.  For the selected frame's buffer list this moves
+   BUFFER to its end even if it was never shown in that frame.  If
+   this happens we have a feature, hence `unrecord-buffer' should be
+   called only when BUFFER was shown in the selected frame.  */
 
-  /* Now move this buffer to the front of frame_buffer_list also.  */
+DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
+       1, 1, 0,
+       doc: /* Move BUFFER to the end of the buffer list.  */)
+  (Lisp_Object buffer)
+{
+  Lisp_Object aelt, aelt_cons, tem;
+  register struct frame *f = XFRAME (selected_frame);
 
-  prev = Qnil;
-  for (list = frame_buffer_list (frame); CONSP (list);
-       list = XCDR (list))
-    {
-      if (EQ (XCAR (list), buf))
-       break;
-      prev = list;
-    }
+  CHECK_BUFFER (buffer);
 
-  /* Effectively do delq.  */
+  /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
+     Don't allow quitting since this might leave the buffer list in an
+     inconsistent state.  */
+  tem = Vinhibit_quit;
+  Vinhibit_quit = Qt;
+  aelt = Frassq (buffer, Vbuffer_alist);
+  aelt_cons = Fmemq (aelt, Vbuffer_alist);
+  Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+  XSETCDR (aelt_cons, Qnil);
+  Vbuffer_alist = nconc2 (Vbuffer_alist, aelt_cons);
+  Vinhibit_quit = tem;
 
-  if (CONSP (list))
-    {
-      if (NILP (prev))
-       set_frame_buffer_list (frame,
-                              XCDR (frame_buffer_list (frame)));
-      else
-       XSETCDR (prev, XCDR (XCDR (prev)));
+  /* Update buffer lists of selected frame.  */
+  f->buffer_list = Fdelq (buffer, f->buffer_list);
+  f->buried_buffer_list = Fcons (buffer, Fdelq (buffer, f->buried_buffer_list));
 
-      XSETCDR (list, frame_buffer_list (frame));
-      set_frame_buffer_list (frame, list);
-    }
-  else
-    set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame)));
+  /* Run buffer-list-update-hook.  */
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
+  return Qnil;
 }
 
 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
@@ -1676,7 +1746,7 @@ Use this function before selecting the buffer, since it may need to inspect
 the current buffer's major mode.  */)
   (Lisp_Object buffer)
 {
-  int count;
+  ptrdiff_t count;
   Lisp_Object function;
 
   CHECK_BUFFER (buffer);
@@ -1708,86 +1778,6 @@ the current buffer's major mode.  */)
   return unbind_to (count, Qnil);
 }
 
-/* Switch to buffer BUFFER in the selected window.
-   If NORECORD is non-nil, don't call record_buffer.  */
-
-static Lisp_Object
-switch_to_buffer_1 (Lisp_Object buffer_or_name, Lisp_Object norecord)
-{
-  register Lisp_Object buffer;
-
-  if (NILP (buffer_or_name))
-    buffer = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      if (NILP (buffer))
-       {
-         buffer = Fget_buffer_create (buffer_or_name);
-         Fset_buffer_major_mode (buffer);
-       }
-    }
-  Fset_buffer (buffer);
-  if (NILP (norecord))
-    record_buffer (buffer);
-
-  Fset_window_buffer (EQ (selected_window, minibuf_window)
-                     ? Fnext_window (minibuf_window, Qnil, Qnil)
-                     : selected_window,
-                     buffer, Qnil);
-
-  return buffer;
-}
-
-DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2,
-       "(list (read-buffer-to-switch \"Switch to buffer: \"))",
-       doc: /* Make BUFFER-OR-NAME current and display it in selected window.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil.  Return the buffer switched to.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name.  Interactively, if
-`confirm-nonexistent-file-or-buffer' is non-nil, request
-confirmation before creating a new buffer.  If BUFFER-OR-NAME is
-nil, switch to buffer returned by `other-buffer'.
-
-Optional second arg NORECORD non-nil means do not put this buffer
-at the front of the list of recently selected ones.  This
-function returns the buffer it switched to as a Lisp object.
-
-If the selected window is the minibuffer window or dedicated to
-its buffer, use `pop-to-buffer' for displaying the buffer.
-
-WARNING: This is NOT the way to work on another buffer temporarily
-within a Lisp program!  Use `set-buffer' instead.  That avoids
-messing with the window-buffer correspondences.  */)
-  (Lisp_Object buffer_or_name, Lisp_Object norecord)
-{
-  if (EQ (buffer_or_name, Fwindow_buffer (selected_window)))
-    {
-      /* Basically a NOP.  Avoid signalling an error in the case where
-        the selected window is dedicated, or a minibuffer.  */
-
-      /* But do put this buffer at the front of the buffer list, unless
-        that has been inhibited.  Note that even if BUFFER-OR-NAME is
-        at the front of the main buffer-list already, we still want to
-        move it to the front of the frame's buffer list.  */
-      if (NILP (norecord))
-       record_buffer (buffer_or_name);
-      return Fset_buffer (buffer_or_name);
-    }
-  else if (EQ (minibuf_window, selected_window)
-          /* If `dedicated' is neither nil nor t, it means it's
-             dedicatedness can be overridden by an explicit request
-             such as a call to switch-to-buffer.  */
-          || EQ (Fwindow_dedicated_p (selected_window), Qt))
-    /* We can't use the selected window so let `pop-to-buffer' try some
-       other window. */
-    return call3 (intern ("pop-to-buffer"), buffer_or_name, Qnil, norecord);
-  else
-    return switch_to_buffer_1 (buffer_or_name, norecord);
-}
-
 DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
        doc: /* Return the current buffer as a Lisp object.  */)
   (void)
@@ -1937,68 +1927,6 @@ DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
     xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
   return Qnil;
 }
-
-DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
-       doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers.
-There it is the least likely candidate for `other-buffer' to return;
-thus, the least likely buffer for \\[switch-to-buffer] to select by
-default.
-
-The argument may be a buffer name or an actual buffer object.  If
-BUFFER-OR-NAME is nil or omitted, bury the current buffer and remove it
-from the selected window if it is displayed there.  If the selected
-window is dedicated to its buffer, delete that window if there are other
-windows on the same frame.  If the selected window is the only window on
-its frame, iconify that frame.  */)
-  (register Lisp_Object buffer_or_name)
-{
-  Lisp_Object buffer;
-
-  /* Figure out what buffer we're going to bury.  */
-  if (NILP (buffer_or_name))
-    {
-      Lisp_Object tem;
-      XSETBUFFER (buffer, current_buffer);
-
-      tem = Fwindow_buffer (selected_window);
-      /* If we're burying the current buffer, unshow it.  */
-      if (EQ (buffer, tem))
-       {
-         if (NILP (Fwindow_dedicated_p (selected_window)))
-           Fswitch_to_buffer (Fother_buffer (buffer, Qnil, Qnil), Qnil);
-         else if (NILP (XWINDOW (selected_window)->parent))
-           Ficonify_frame (Fwindow_frame (selected_window));
-         else
-           Fdelete_window (selected_window);
-       }
-    }
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      if (NILP (buffer))
-       nsberror (buffer_or_name);
-    }
-
-  /* Move buffer to the end of the buffer list.  Do nothing if the
-     buffer is killed.  */
-  if (!NILP (BVAR (XBUFFER (buffer), name)))
-    {
-      Lisp_Object aelt, list;
-
-      aelt = Frassq (buffer, Vbuffer_alist);
-      list = Fmemq (aelt, Vbuffer_alist);
-      Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
-      XSETCDR (list, Qnil);
-      Vbuffer_alist = nconc2 (Vbuffer_alist, list);
-
-      XFRAME (selected_frame)->buffer_list
-        = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
-      XFRAME (selected_frame)->buried_buffer_list
-        = Fcons (buffer, Fdelq (buffer, XFRAME (selected_frame)->buried_buffer_list));
-    }
-
-  return Qnil;
-}
 \f
 DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
        doc: /* Delete the entire contents of the current buffer.
@@ -2030,16 +1958,15 @@ validate_region (register Lisp_Object *b, register Lisp_Object *e)
       tem = *b;  *b = *e;  *e = tem;
     }
 
-  if (!(BEGV <= XINT (*b) && XINT (*b) <= XINT (*e)
-        && XINT (*e) <= ZV))
+  if (! (BEGV <= XINT (*b) && XINT (*e) <= ZV))
     args_out_of_range (*b, *e);
 }
 \f
 /* Advance BYTE_POS up to a character boundary
    and return the adjusted position.  */
 
-static EMACS_INT
-advance_to_char_boundary (EMACS_INT byte_pos)
+static ptrdiff_t
+advance_to_char_boundary (ptrdiff_t byte_pos)
 {
   int c;
 
@@ -2052,7 +1979,7 @@ advance_to_char_boundary (EMACS_INT byte_pos)
     {
       /* We should advance BYTE_POS only when C is a constituent of a
          multibyte sequence.  */
-      EMACS_INT orig_byte_pos = byte_pos;
+      ptrdiff_t orig_byte_pos = byte_pos;
 
       do
        {
@@ -2128,12 +2055,12 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
                          (POINTER_TYPE **) &current_buffer->own_text.beg);
 #endif /* REL_ALLOC */
 
-  swapfield (pt, EMACS_INT);
-  swapfield (pt_byte, EMACS_INT);
-  swapfield (begv, EMACS_INT);
-  swapfield (begv_byte, EMACS_INT);
-  swapfield (zv, EMACS_INT);
-  swapfield (zv_byte, EMACS_INT);
+  swapfield (pt, ptrdiff_t);
+  swapfield (pt_byte, ptrdiff_t);
+  swapfield (begv, ptrdiff_t);
+  swapfield (begv_byte, ptrdiff_t);
+  swapfield (zv, ptrdiff_t);
+  swapfield (zv_byte, ptrdiff_t);
   eassert (!current_buffer->base_buffer);
   eassert (!other_buffer->base_buffer);
   current_buffer->clip_changed = 1;    other_buffer->clip_changed = 1;
@@ -2143,7 +2070,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
   other_buffer->prevent_redisplay_optimizations_p = 1;
   swapfield (overlays_before, struct Lisp_Overlay *);
   swapfield (overlays_after, struct Lisp_Overlay *);
-  swapfield (overlay_center, EMACS_INT);
+  swapfield (overlay_center, ptrdiff_t);
   swapfield_ (undo_list, Lisp_Object);
   swapfield_ (mark, Lisp_Object);
   swapfield_ (enable_multibyte_characters, Lisp_Object);
@@ -2226,7 +2153,7 @@ current buffer is cleared.  */)
 {
   struct Lisp_Marker *tail, *markers;
   struct buffer *other;
-  EMACS_INT begv, zv;
+  ptrdiff_t begv, zv;
   int narrowed = (BEG != BEGV || Z != ZV);
   int modified_p = !NILP (Fbuffer_modified_p (Qnil));
   Lisp_Object old_undo = BVAR (current_buffer, undo_list);
@@ -2258,7 +2185,7 @@ current buffer is cleared.  */)
 
   if (NILP (flag))
     {
-      EMACS_INT pos, stop;
+      ptrdiff_t pos, stop;
       unsigned char *p;
 
       /* Do this first, so it can use CHAR_TO_BYTE
@@ -2322,8 +2249,8 @@ current buffer is cleared.  */)
     }
   else
     {
-      EMACS_INT pt = PT;
-      EMACS_INT pos, stop;
+      ptrdiff_t pt = PT;
+      ptrdiff_t pos, stop;
       unsigned char *p, *pend;
 
       /* Be sure not to have a multibyte sequence striding over the GAP.
@@ -2339,7 +2266,7 @@ current buffer is cleared.  */)
          while (! CHAR_HEAD_P (*q) && q > BEG_ADDR) q--;
          if (LEADING_CODE_P (*q))
            {
-             EMACS_INT new_gpt = GPT_BYTE - (GPT_ADDR - q);
+             ptrdiff_t new_gpt = GPT_BYTE - (GPT_ADDR - q);
 
              move_gap_both (new_gpt, new_gpt);
            }
@@ -2423,8 +2350,8 @@ current buffer is cleared.  */)
        ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
 
       {
-       EMACS_INT byte = advance_to_char_boundary (PT_BYTE);
-       EMACS_INT position;
+       ptrdiff_t byte = advance_to_char_boundary (PT_BYTE);
+       ptrdiff_t position;
 
        if (byte > GPT_BYTE)
          position = chars_in_text (GAP_END_ADDR, byte - GPT_BYTE) + GPT;
@@ -2585,22 +2512,23 @@ swap_out_buffer_local_variables (struct buffer *b)
    *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
    default (BEGV or ZV).  */
 
-int
-overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
-            EMACS_INT *next_ptr, EMACS_INT *prev_ptr, int change_req)
+ptrdiff_t
+overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
+            ptrdiff_t *len_ptr,
+            ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, int change_req)
 {
   Lisp_Object overlay, start, end;
   struct Lisp_Overlay *tail;
-  int idx = 0;
-  int len = *len_ptr;
+  ptrdiff_t idx = 0;
+  ptrdiff_t len = *len_ptr;
   Lisp_Object *vec = *vec_ptr;
-  EMACS_INT next = ZV;
-  EMACS_INT prev = BEGV;
+  ptrdiff_t next = ZV;
+  ptrdiff_t prev = BEGV;
   int inhibit_storing = 0;
 
   for (tail = current_buffer->overlays_before; tail; tail = tail->next)
     {
-      EMACS_INT startpos, endpos;
+      ptrdiff_t startpos, endpos;
 
       XSETMISC (overlay, tail);
 
@@ -2628,13 +2556,10 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
                 Either make it bigger, or don't store any more in it.  */
              if (extend)
                {
-                 /* Make it work with an initial len == 0.  */
-                 len *= 2;
-                 if (len == 0)
-                   len = 4;
-                 *len_ptr = len;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2651,7 +2576,7 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
 
   for (tail = current_buffer->overlays_after; tail; tail = tail->next)
     {
-      EMACS_INT startpos, endpos;
+      ptrdiff_t startpos, endpos;
 
       XSETMISC (overlay, tail);
 
@@ -2671,13 +2596,10 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
            {
              if (extend)
                {
-                 /* Make it work with an initial len == 0.  */
-                 len *= 2;
-                 if (len == 0)
-                   len = 4;
-                 *len_ptr = len;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2724,24 +2646,24 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
    and we store only as many overlays as will fit.
    But we still return the total number of overlays.  */
 
-static int
+static ptrdiff_t
 overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
-            Lisp_Object **vec_ptr, int *len_ptr,
-            EMACS_INT *next_ptr, EMACS_INT *prev_ptr)
+            Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
+            ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
 {
   Lisp_Object overlay, ostart, oend;
   struct Lisp_Overlay *tail;
-  int idx = 0;
-  int len = *len_ptr;
+  ptrdiff_t idx = 0;
+  ptrdiff_t len = *len_ptr;
   Lisp_Object *vec = *vec_ptr;
-  EMACS_INT next = ZV;
-  EMACS_INT prev = BEGV;
+  ptrdiff_t next = ZV;
+  ptrdiff_t prev = BEGV;
   int inhibit_storing = 0;
   int end_is_Z = end == Z;
 
   for (tail = current_buffer->overlays_before; tail; tail = tail->next)
     {
-      EMACS_INT startpos, endpos;
+      ptrdiff_t startpos, endpos;
 
       XSETMISC (overlay, tail);
 
@@ -2768,13 +2690,10 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
                 Either make it bigger, or don't store any more in it.  */
              if (extend)
                {
-                 /* Make it work with an initial len == 0.  */
-                 len *= 2;
-                 if (len == 0)
-                   len = 4;
-                 *len_ptr = len;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2791,7 +2710,7 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
 
   for (tail = current_buffer->overlays_after; tail; tail = tail->next)
     {
-      EMACS_INT startpos, endpos;
+      ptrdiff_t startpos, endpos;
 
       XSETMISC (overlay, tail);
 
@@ -2816,13 +2735,10 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
            {
              if (extend)
                {
-                 /* Make it work with an initial len == 0.  */
-                 len *= 2;
-                 if (len == 0)
-                   len = 4;
-                 *len_ptr = len;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2850,9 +2766,9 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
 int
 mouse_face_overlay_overlaps (Lisp_Object overlay)
 {
-  EMACS_INT start = OVERLAY_POSITION (OVERLAY_START (overlay));
-  EMACS_INT end = OVERLAY_POSITION (OVERLAY_END (overlay));
-  int n, i, size;
+  ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
+  ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
+  ptrdiff_t n, i, size;
   Lisp_Object *v, tem;
 
   size = 10;
@@ -2877,14 +2793,14 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
 \f
 /* Fast function to just test if we're at an overlay boundary.  */
 int
-overlay_touches_p (EMACS_INT pos)
+overlay_touches_p (ptrdiff_t pos)
 {
   Lisp_Object overlay;
   struct Lisp_Overlay *tail;
 
   for (tail = current_buffer->overlays_before; tail; tail = tail->next)
     {
-      EMACS_INT endpos;
+      ptrdiff_t endpos;
 
       XSETMISC (overlay ,tail);
       if (!OVERLAYP (overlay))
@@ -2899,7 +2815,7 @@ overlay_touches_p (EMACS_INT pos)
 
   for (tail = current_buffer->overlays_after; tail; tail = tail->next)
     {
-      EMACS_INT startpos;
+      ptrdiff_t startpos;
 
       XSETMISC (overlay, tail);
       if (!OVERLAYP (overlay))
@@ -2917,8 +2833,8 @@ overlay_touches_p (EMACS_INT pos)
 struct sortvec
 {
   Lisp_Object overlay;
-  EMACS_INT beg, end;
-  int priority;
+  ptrdiff_t beg, end;
+  EMACS_INT priority;
 };
 
 static int
@@ -2927,21 +2843,21 @@ compare_overlays (const void *v1, const void *v2)
   const struct sortvec *s1 = (const struct sortvec *) v1;
   const struct sortvec *s2 = (const struct sortvec *) v2;
   if (s1->priority != s2->priority)
-    return s1->priority - s2->priority;
+    return s1->priority < s2->priority ? -1 : 1;
   if (s1->beg != s2->beg)
-    return s1->beg - s2->beg;
+    return s1->beg < s2->beg ? -1 : 1;
   if (s1->end != s2->end)
-    return s2->end - s1->end;
+    return s2->end < s1->end ? -1 : 1;
   return 0;
 }
 
 /* Sort an array of overlays by priority.  The array is modified in place.
    The return value is the new size; this may be smaller than the original
    size if some of the overlays were invalid or were window-specific.  */
-int
-sort_overlays (Lisp_Object *overlay_vec, int noverlays, struct window *w)
+ptrdiff_t
+sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
 {
-  int i, j;
+  ptrdiff_t i, j;
   struct sortvec *sortvec;
   sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
 
@@ -2995,16 +2911,16 @@ sort_overlays (Lisp_Object *overlay_vec, int noverlays, struct window *w)
 struct sortstr
 {
   Lisp_Object string, string2;
-  int size;
-  int priority;
+  ptrdiff_t size;
+  EMACS_INT priority;
 };
 
 struct sortstrlist
 {
   struct sortstr *buf; /* An array that expands as needed; never freed.  */
-  int size;            /* Allocated length of that array.  */
-  int used;            /* How much of the array is currently in use.  */
-  EMACS_INT bytes;             /* Total length of the strings in buf.  */
+  ptrdiff_t size;      /* Allocated length of that array.  */
+  ptrdiff_t used;      /* How much of the array is currently in use.  */
+  ptrdiff_t bytes;     /* Total length of the strings in buf.  */
 };
 
 /* Buffers for storing information about the overlays touching a given
@@ -3015,7 +2931,7 @@ static struct sortstrlist overlay_heads, overlay_tails;
 static unsigned char *overlay_str_buf;
 
 /* Allocated length of overlay_str_buf.  */
-static EMACS_INT overlay_str_len;
+static ptrdiff_t overlay_str_len;
 
 /* A comparison function suitable for passing to qsort.  */
 static int
@@ -3024,26 +2940,20 @@ cmp_for_strings (const void *as1, const void *as2)
   struct sortstr *s1 = (struct sortstr *)as1;
   struct sortstr *s2 = (struct sortstr *)as2;
   if (s1->size != s2->size)
-    return s2->size - s1->size;
+    return s2->size < s1->size ? -1 : 1;
   if (s1->priority != s2->priority)
-    return s1->priority - s2->priority;
+    return s1->priority < s2->priority ? -1 : 1;
   return 0;
 }
 
 static void
-record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str2, Lisp_Object pri, int size)
+record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
+                      Lisp_Object str2, Lisp_Object pri, ptrdiff_t size)
 {
-  EMACS_INT nbytes;
+  ptrdiff_t nbytes;
 
   if (ssl->used == ssl->size)
-    {
-      if (ssl->buf)
-       ssl->size *= 2;
-      else
-       ssl->size = 5;
-      ssl->buf = ((struct sortstr *)
-                 xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
-    }
+    ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf);
   ssl->buf[ssl->used].string = str;
   ssl->buf[ssl->used].string2 = str2;
   ssl->buf[ssl->used].size = size;
@@ -3058,6 +2968,8 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str
   else
     nbytes = SBYTES (str);
 
+  if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+    memory_full (SIZE_MAX);
   ssl->bytes += nbytes;
 
   if (STRINGP (str2))
@@ -3070,6 +2982,8 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str
       else
        nbytes = SBYTES (str2);
 
+      if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+       memory_full (SIZE_MAX);
       ssl->bytes += nbytes;
     }
 }
@@ -3086,12 +3000,12 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str
    PSTR, if that variable is non-null.  The string may be overwritten by
    subsequent calls.  */
 
-EMACS_INT
-overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
+ptrdiff_t
+overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
 {
   Lisp_Object overlay, window, str;
   struct Lisp_Overlay *ov;
-  EMACS_INT startpos, endpos;
+  ptrdiff_t startpos, endpos;
   int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
 
   overlay_heads.used = overlay_heads.bytes = 0;
@@ -3161,20 +3075,21 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
   if (overlay_heads.bytes || overlay_tails.bytes)
     {
       Lisp_Object tem;
-      EMACS_INT i;
+      ptrdiff_t i;
       unsigned char *p;
-      EMACS_INT total = overlay_heads.bytes + overlay_tails.bytes;
+      ptrdiff_t total;
 
+      if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes))
+       memory_full (SIZE_MAX);
+      total = overlay_heads.bytes + overlay_tails.bytes;
       if (total > overlay_str_len)
-       {
-         overlay_str_len = total;
-         overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
-                                                      total);
-       }
+       overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
+                                  total - overlay_str_len, -1, 1);
+
       p = overlay_str_buf;
       for (i = overlay_tails.used; --i >= 0;)
        {
-         EMACS_INT nbytes;
+         ptrdiff_t nbytes;
          tem = overlay_tails.buf[i].string;
          nbytes = copy_text (SDATA (tem), p,
                              SBYTES (tem),
@@ -3183,7 +3098,7 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
        }
       for (i = 0; i < overlay_heads.used; ++i)
        {
-         EMACS_INT nbytes;
+         ptrdiff_t nbytes;
          tem = overlay_heads.buf[i].string;
          nbytes = copy_text (SDATA (tem), p,
                              SBYTES (tem),
@@ -3210,7 +3125,7 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
 /* Shift overlays in BUF's overlay lists, to center the lists at POS.  */
 
 void
-recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
+recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
 {
   Lisp_Object overlay, beg, end;
   struct Lisp_Overlay *prev, *tail, *next;
@@ -3248,7 +3163,7 @@ recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
       if (OVERLAY_POSITION (end) > pos)
        {
          /* OVERLAY needs to be moved.  */
-         EMACS_INT where = OVERLAY_POSITION (beg);
+         ptrdiff_t where = OVERLAY_POSITION (beg);
          struct Lisp_Overlay *other, *other_prev;
 
          /* Splice the cons cell TAIL out of overlays_before.  */
@@ -3321,7 +3236,7 @@ recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
       if (OVERLAY_POSITION (end) <= pos)
        {
          /* OVERLAY needs to be moved.  */
-         EMACS_INT where = OVERLAY_POSITION (end);
+         ptrdiff_t where = OVERLAY_POSITION (end);
          struct Lisp_Overlay *other, *other_prev;
 
          /* Splice the cons cell TAIL out of overlays_after.  */
@@ -3359,7 +3274,7 @@ recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
 }
 
 void
-adjust_overlays_for_insert (EMACS_INT pos, EMACS_INT length)
+adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
 {
   /* After an insertion, the lists are still sorted properly,
      but we may need to update the value of the overlay center.  */
@@ -3368,13 +3283,13 @@ adjust_overlays_for_insert (EMACS_INT pos, EMACS_INT length)
 }
 
 void
-adjust_overlays_for_delete (EMACS_INT pos, EMACS_INT length)
+adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
 {
   if (current_buffer->overlay_center < pos)
     /* The deletion was to our right.  No change needed; the before- and
        after-lists are still consistent.  */
     ;
-  else if (current_buffer->overlay_center > pos + length)
+  else if (current_buffer->overlay_center - pos > length)
     /* The deletion was to our left.  We need to adjust the center value
        to account for the change in position, but the lists are consistent
        given the new value.  */
@@ -3393,7 +3308,7 @@ adjust_overlays_for_delete (EMACS_INT pos, EMACS_INT length)
    Such an overlay might even have negative size at this point.
    If so, we'll make the overlay empty. */
 void
-fix_start_end_in_overlays (register EMACS_INT start, register EMACS_INT end)
+fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
 {
   Lisp_Object overlay;
   struct Lisp_Overlay *before_list IF_LINT (= NULL);
@@ -3406,7 +3321,7 @@ fix_start_end_in_overlays (register EMACS_INT start, register EMACS_INT end)
      current_buffer->overlays_before or overlays_after, depending
      which loop we're in.  */
   struct Lisp_Overlay *tail, *parent;
-  EMACS_INT startpos, endpos;
+  ptrdiff_t startpos, endpos;
 
   /* This algorithm shifts links around instead of consing and GCing.
      The loop invariant is that before_list (resp. after_list) is a
@@ -3540,12 +3455,12 @@ fix_start_end_in_overlays (register EMACS_INT start, register EMACS_INT end)
    was at PREV, and now is at POS.  */
 
 void
-fix_overlays_before (struct buffer *bp, EMACS_INT prev, EMACS_INT pos)
+fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
 {
   /* If parent is nil, replace overlays_before; otherwise, parent->next.  */
   struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
   Lisp_Object tem;
-  EMACS_INT end IF_LINT (= 0);
+  ptrdiff_t end IF_LINT (= 0);
 
   /* After the insertion, the several overlays may be in incorrect
      order.  The possibility is that, in the list `overlays_before',
@@ -3703,11 +3618,11 @@ for the rear of the overlay advance when text is inserted there
 /* Mark a section of BUF as needing redisplay because of overlays changes.  */
 
 static void
-modify_overlay (struct buffer *buf, EMACS_INT start, EMACS_INT end)
+modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
 {
   if (start > end)
     {
-      EMACS_INT temp = start;
+      ptrdiff_t temp = start;
       start = end;
       end = temp;
     }
@@ -3756,7 +3671,7 @@ buffer.  */)
 {
   struct buffer *b, *ob;
   Lisp_Object obuffer;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   CHECK_OVERLAY (overlay);
   if (NILP (buffer))
@@ -3775,19 +3690,22 @@ buffer.  */)
   CHECK_NUMBER_COERCE_MARKER (beg);
   CHECK_NUMBER_COERCE_MARKER (end);
 
-  if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
-    return Fdelete_overlay (overlay);
-
   if (XINT (beg) > XINT (end))
     {
       Lisp_Object temp;
       temp = beg; beg = end; end = temp;
     }
 
+  b = XBUFFER (buffer);
+  if (! (BUF_BEGV (b) <= XINT (beg) && XINT (end) <= BUF_ZV (b)))
+    args_out_of_range (beg, end);
+
+  if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
+    return Fdelete_overlay (overlay);
+
   specbind (Qinhibit_quit, Qt);
 
   obuffer = Fmarker_buffer (OVERLAY_START (overlay));
-  b = XBUFFER (buffer);
   ob = BUFFERP (obuffer) ? XBUFFER (obuffer) : (struct buffer *) 0;
 
   /* If the overlay has changed buffers, do a thorough redisplay.  */
@@ -3796,8 +3714,8 @@ buffer.  */)
       /* Redisplay where the overlay was.  */
       if (!NILP (obuffer))
        {
-         EMACS_INT o_beg;
-         EMACS_INT o_end;
+         ptrdiff_t o_beg;
+         ptrdiff_t o_end;
 
          o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
          o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
@@ -3811,7 +3729,7 @@ buffer.  */)
   else
     /* Redisplay the area the overlay has just left, or just enclosed.  */
     {
-      EMACS_INT o_beg, o_end;
+      ptrdiff_t o_beg, o_end;
 
       o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
       o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
@@ -3865,7 +3783,7 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
 {
   Lisp_Object buffer;
   struct buffer *b;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   CHECK_OVERLAY (overlay);
 
@@ -3943,9 +3861,8 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
        doc: /* Return a list of the overlays that contain the character at POS.  */)
   (Lisp_Object pos)
 {
-  int noverlays;
+  ptrdiff_t len, noverlays;
   Lisp_Object *overlay_vec;
-  int len;
   Lisp_Object result;
 
   CHECK_NUMBER_COERCE_MARKER (pos);
@@ -3957,7 +3874,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
   noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
-                          (EMACS_INT *) 0, (EMACS_INT *) 0, 0);
+                          0, 0, 0);
 
   /* Make a list of them all.  */
   result = Flist (noverlays, overlay_vec);
@@ -3975,9 +3892,8 @@ between BEG and END, or at END provided END denotes the position at the
 end of the buffer.  */)
   (Lisp_Object beg, Lisp_Object end)
 {
-  int noverlays;
+  ptrdiff_t len, noverlays;
   Lisp_Object *overlay_vec;
-  int len;
   Lisp_Object result;
 
   CHECK_NUMBER_COERCE_MARKER (beg);
@@ -4005,11 +3921,9 @@ If there are no overlay boundaries from POS to (point-max),
 the value is (point-max).  */)
   (Lisp_Object pos)
 {
-  int noverlays;
-  EMACS_INT endpos;
+  ptrdiff_t i, len, noverlays;
+  ptrdiff_t endpos;
   Lisp_Object *overlay_vec;
-  int len;
-  int i;
 
   CHECK_NUMBER_COERCE_MARKER (pos);
 
@@ -4020,14 +3934,14 @@ the value is (point-max).  */)
      Store the length in len.
      endpos gets the position where the next overlay starts.  */
   noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
-                          &endpos, (EMACS_INT *) 0, 1);
+                          &endpos, 0, 1);
 
   /* If any of these overlays ends before endpos,
      use its ending point instead.  */
   for (i = 0; i < noverlays; i++)
     {
       Lisp_Object oend;
-      EMACS_INT oendpos;
+      ptrdiff_t oendpos;
 
       oend = OVERLAY_END (overlay_vec[i]);
       oendpos = OVERLAY_POSITION (oend);
@@ -4046,9 +3960,9 @@ If there are no overlay boundaries from (point-min) to POS,
 the value is (point-min).  */)
   (Lisp_Object pos)
 {
-  EMACS_INT prevpos;
+  ptrdiff_t prevpos;
   Lisp_Object *overlay_vec;
-  int len;
+  ptrdiff_t len;
 
   CHECK_NUMBER_COERCE_MARKER (pos);
 
@@ -4064,7 +3978,7 @@ the value is (point-min).  */)
      Store the length in len.
      prevpos gets the position of the previous change.  */
   overlays_at (XINT (pos), 1, &overlay_vec, &len,
-              (EMACS_INT *) 0, &prevpos, 1);
+              0, &prevpos, 1);
 
   xfree (overlay_vec);
   return make_number (prevpos);
@@ -4102,9 +4016,11 @@ That makes overlay lookup faster for positions near POS (but perhaps slower
 for positions far away from POS).  */)
   (Lisp_Object pos)
 {
+  ptrdiff_t p;
   CHECK_NUMBER_COERCE_MARKER (pos);
 
-  recenter_overlay_lists (current_buffer, XINT (pos));
+  p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX);
+  recenter_overlay_lists (current_buffer, p);
   return Qnil;
 }
 \f
@@ -4117,7 +4033,8 @@ DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
 }
 
 DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
-       doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE.  */)
+       doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE.
+VALUE will be returned.*/)
   (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
 {
   Lisp_Object tail, buffer;
@@ -4170,7 +4087,7 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
 static Lisp_Object last_overlay_modification_hooks;
 
 /* Number of elements actually used in last_overlay_modification_hooks.  */
-static int last_overlay_modification_hooks_used;
+static ptrdiff_t last_overlay_modification_hooks_used;
 
 /* Add one functionlist/overlay pair
    to the end of last_overlay_modification_hooks.  */
@@ -4178,11 +4095,11 @@ static int last_overlay_modification_hooks_used;
 static void
 add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
 {
-  int oldsize = ASIZE (last_overlay_modification_hooks);
+  ptrdiff_t oldsize = ASIZE (last_overlay_modification_hooks);
 
-  if (last_overlay_modification_hooks_used == oldsize)
-    last_overlay_modification_hooks = larger_vector
-      (last_overlay_modification_hooks, oldsize * 2, Qnil);
+  if (oldsize - 1 <= last_overlay_modification_hooks_used)
+    last_overlay_modification_hooks =
+      larger_vector (last_overlay_modification_hooks, 2, -1);
   ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
        functionlist); last_overlay_modification_hooks_used++;
   ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
@@ -4231,7 +4148,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
       last_overlay_modification_hooks_used = 0;
       for (tail = current_buffer->overlays_before; tail; tail = tail->next)
        {
-         EMACS_INT startpos, endpos;
+         ptrdiff_t startpos, endpos;
          Lisp_Object ostart, oend;
 
          XSETMISC (overlay, tail);
@@ -4268,7 +4185,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
 
       for (tail = current_buffer->overlays_after; tail; tail = tail->next)
        {
-         EMACS_INT startpos, endpos;
+         ptrdiff_t startpos, endpos;
          Lisp_Object ostart, oend;
 
          XSETMISC (overlay, tail);
@@ -4309,9 +4226,9 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
     /* Call the functions recorded in last_overlay_modification_hooks.
        First copy the vector contents, in case some of these hooks
        do subsequent modification of the buffer.  */
-    int size = last_overlay_modification_hooks_used;
+    ptrdiff_t size = last_overlay_modification_hooks_used;
     Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
-    int i;
+    ptrdiff_t i;
 
     memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
            size * sizeof (Lisp_Object));
@@ -4351,7 +4268,7 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, int after,
 /* Delete any zero-sized overlays at position POS, if the `evaporate'
    property is set.  */
 void
-evaporate_overlays (EMACS_INT pos)
+evaporate_overlays (ptrdiff_t pos)
 {
   Lisp_Object overlay, hit_list;
   struct Lisp_Overlay *tail;
@@ -4360,7 +4277,7 @@ evaporate_overlays (EMACS_INT pos)
   if (pos <= current_buffer->overlay_center)
     for (tail = current_buffer->overlays_before; tail; tail = tail->next)
       {
-       EMACS_INT endpos;
+       ptrdiff_t endpos;
        XSETMISC (overlay, tail);
        endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
        if (endpos < pos)
@@ -4372,7 +4289,7 @@ evaporate_overlays (EMACS_INT pos)
   else
     for (tail = current_buffer->overlays_after; tail; tail = tail->next)
       {
-       EMACS_INT startpos;
+       ptrdiff_t startpos;
        XSETMISC (overlay, tail);
        startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
        if (startpos > pos)
@@ -4526,24 +4443,40 @@ static int mmap_initialized_p;
 #define MMAP_ALLOCATED_P(start, end) 1
 #endif
 
-/* Function prototypes.  */
+/* Perform necessary intializations for the use of mmap.  */
 
-static int mmap_free_1 (struct mmap_region *);
-static int mmap_enlarge (struct mmap_region *, int);
-static struct mmap_region *mmap_find (POINTER_TYPE *, POINTER_TYPE *);
-static POINTER_TYPE *mmap_alloc (POINTER_TYPE **, size_t);
-static POINTER_TYPE *mmap_realloc (POINTER_TYPE **, size_t);
-static void mmap_free (POINTER_TYPE **ptr);
-static void mmap_init (void);
+static void
+mmap_init (void)
+{
+#if MAP_ANON == 0
+  /* The value of mmap_fd is initially 0 in temacs, and -1
+     in a dumped Emacs.  */
+  if (mmap_fd <= 0)
+    {
+      /* No anonymous mmap -- we need the file descriptor.  */
+      mmap_fd = open ("/dev/zero", O_RDONLY);
+      if (mmap_fd == -1)
+       fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
+    }
+#endif /* MAP_ANON == 0 */
+
+  if (mmap_initialized_p)
+    return;
+  mmap_initialized_p = 1;
+
+#if MAP_ANON != 0
+  mmap_fd = -1;
+#endif
 
+  mmap_page_size = getpagesize ();
+}
 
 /* Return a region overlapping address range START...END, or null if
    none.  END is not including, i.e. the last byte in the range
    is at END - 1.  */
 
 static struct mmap_region *
-mmap_find (start, end)
-     POINTER_TYPE *start, *end;
+mmap_find (POINTER_TYPE *start, POINTER_TYPE *end)
 {
   struct mmap_region *r;
   char *s = (char *) start, *e = (char *) end;
@@ -4572,8 +4505,7 @@ mmap_find (start, end)
    the region.  Value is non-zero if successful.  */
 
 static int
-mmap_free_1 (r)
-     struct mmap_region *r;
+mmap_free_1 (struct mmap_region *r)
 {
   if (r->next)
     r->next->prev = r->prev;
@@ -4596,9 +4528,7 @@ mmap_free_1 (r)
    Value is non-zero if successful.  */
 
 static int
-mmap_enlarge (r, npages)
-     struct mmap_region *r;
-     int npages;
+mmap_enlarge (struct mmap_region *r, int npages)
 {
   char *region_end = (char *) r + r->nbytes_mapped;
   size_t nbytes;
@@ -4662,8 +4592,7 @@ mmap_enlarge (r, npages)
    when Emacs starts.  */
 
 void
-mmap_set_vars (restore_p)
-     int restore_p;
+mmap_set_vars (int restore_p)
 {
   struct mmap_region *r;
 
@@ -4696,9 +4625,7 @@ mmap_set_vars (restore_p)
    return null.  */
 
 static POINTER_TYPE *
-mmap_alloc (var, nbytes)
-     POINTER_TYPE **var;
-     size_t nbytes;
+mmap_alloc (POINTER_TYPE **var, size_t nbytes)
 {
   void *p;
   size_t map;
@@ -4735,15 +4662,29 @@ mmap_alloc (var, nbytes)
 }
 
 
+/* Free a block of relocatable storage whose data is pointed to by
+   PTR.  Store 0 in *PTR to show there's no block allocated.  */
+
+static void
+mmap_free (POINTER_TYPE **var)
+{
+  mmap_init ();
+
+  if (*var)
+    {
+      mmap_free_1 (MMAP_REGION (*var));
+      *var = NULL;
+    }
+}
+
+
 /* Given a pointer at address VAR to data allocated with mmap_alloc,
    resize it to size NBYTES.  Change *VAR to reflect the new block,
    and return this value.  If more memory cannot be allocated, then
    leave *VAR unchanged, and return null.  */
 
 static POINTER_TYPE *
-mmap_realloc (var, nbytes)
-     POINTER_TYPE **var;
-     size_t nbytes;
+mmap_realloc (POINTER_TYPE **var, size_t nbytes)
 {
   POINTER_TYPE *result;
 
@@ -4813,51 +4754,6 @@ mmap_realloc (var, nbytes)
 }
 
 
-/* Free a block of relocatable storage whose data is pointed to by
-   PTR.  Store 0 in *PTR to show there's no block allocated.  */
-
-static void
-mmap_free (var)
-     POINTER_TYPE **var;
-{
-  mmap_init ();
-
-  if (*var)
-    {
-      mmap_free_1 (MMAP_REGION (*var));
-      *var = NULL;
-    }
-}
-
-
-/* Perform necessary intializations for the use of mmap.  */
-
-static void
-mmap_init ()
-{
-#if MAP_ANON == 0
-  /* The value of mmap_fd is initially 0 in temacs, and -1
-     in a dumped Emacs.  */
-  if (mmap_fd <= 0)
-    {
-      /* No anonymous mmap -- we need the file descriptor.  */
-      mmap_fd = open ("/dev/zero", O_RDONLY);
-      if (mmap_fd == -1)
-       fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
-    }
-#endif /* MAP_ANON == 0 */
-
-  if (mmap_initialized_p)
-    return;
-  mmap_initialized_p = 1;
-
-#if MAP_ANON != 0
-  mmap_fd = -1;
-#endif
-
-  mmap_page_size = getpagesize ();
-}
-
 #endif /* USE_MMAP_FOR_BUFFERS */
 
 
@@ -4876,7 +4772,7 @@ extern void r_alloc_free (POINTER_TYPE **ptr);
 /* Allocate NBYTES bytes for buffer B's text buffer.  */
 
 static void
-alloc_buffer_text (struct buffer *b, size_t nbytes)
+alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
 {
   POINTER_TYPE *p;
 
@@ -4903,11 +4799,11 @@ alloc_buffer_text (struct buffer *b, size_t nbytes)
    shrink it.  */
 
 void
-enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
+enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
 {
   POINTER_TYPE *p;
-  size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
-                  + delta);
+  ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
+                     + delta);
   BLOCK_INPUT;
 #if defined USE_MMAP_FOR_BUFFERS
   p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);
@@ -5006,7 +4902,7 @@ init_buffer_once (void)
   BVAR (&buffer_defaults, truncate_lines) = Qnil;
   BVAR (&buffer_defaults, word_wrap) = Qnil;
   BVAR (&buffer_defaults, ctl_arrow) = Qt;
-  BVAR (&buffer_defaults, bidi_display_reordering) = Qnil;
+  BVAR (&buffer_defaults, bidi_display_reordering) = Qt;
   BVAR (&buffer_defaults, bidi_paragraph_direction) = Qnil;
   BVAR (&buffer_defaults, cursor_type) = Qt;
   BVAR (&buffer_defaults, extra_line_spacing) = Qnil;
@@ -5040,7 +4936,7 @@ init_buffer_once (void)
      The local flag bits are in the local_var_flags slot of the buffer.  */
 
   /* Nothing can work if this isn't true */
-  if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
+  { verify (sizeof (EMACS_INT) == sizeof (Lisp_Object)); }
 
   /* 0 means not a lisp var, -1 means always local, else mask */
   memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
@@ -5146,7 +5042,7 @@ init_buffer (void)
 {
   char *pwd;
   Lisp_Object temp;
-  int len;
+  ptrdiff_t len;
 
 #ifdef USE_MMAP_FOR_BUFFERS
  {
@@ -5270,39 +5166,26 @@ syms_of_buffer (void)
   staticpro (&Vbuffer_alist);
   staticpro (&Qprotected_field);
   staticpro (&Qpermanent_local);
-  Qpermanent_local_hook = intern_c_string ("permanent-local-hook");
-  staticpro (&Qpermanent_local_hook);
   staticpro (&Qkill_buffer_hook);
-  Qoverlayp = intern_c_string ("overlayp");
-  staticpro (&Qoverlayp);
-  Qevaporate = intern_c_string ("evaporate");
-  staticpro (&Qevaporate);
-  Qmodification_hooks = intern_c_string ("modification-hooks");
-  staticpro (&Qmodification_hooks);
-  Qinsert_in_front_hooks = intern_c_string ("insert-in-front-hooks");
-  staticpro (&Qinsert_in_front_hooks);
-  Qinsert_behind_hooks = intern_c_string ("insert-behind-hooks");
-  staticpro (&Qinsert_behind_hooks);
-  Qget_file_buffer = intern_c_string ("get-file-buffer");
-  staticpro (&Qget_file_buffer);
-  Qpriority = intern_c_string ("priority");
-  staticpro (&Qpriority);
-  Qbefore_string = intern_c_string ("before-string");
-  staticpro (&Qbefore_string);
-  Qafter_string = intern_c_string ("after-string");
-  staticpro (&Qafter_string);
-  Qfirst_change_hook = intern_c_string ("first-change-hook");
-  staticpro (&Qfirst_change_hook);
-  Qbefore_change_functions = intern_c_string ("before-change-functions");
-  staticpro (&Qbefore_change_functions);
-  Qafter_change_functions = intern_c_string ("after-change-functions");
-  staticpro (&Qafter_change_functions);
+
+  DEFSYM (Qpermanent_local_hook, "permanent-local-hook");
+  DEFSYM (Qoverlayp, "overlayp");
+  DEFSYM (Qevaporate, "evaporate");
+  DEFSYM (Qmodification_hooks, "modification-hooks");
+  DEFSYM (Qinsert_in_front_hooks, "insert-in-front-hooks");
+  DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks");
+  DEFSYM (Qget_file_buffer, "get-file-buffer");
+  DEFSYM (Qpriority, "priority");
+  DEFSYM (Qbefore_string, "before-string");
+  DEFSYM (Qafter_string, "after-string");
+  DEFSYM (Qfirst_change_hook, "first-change-hook");
+  DEFSYM (Qbefore_change_functions, "before-change-functions");
+  DEFSYM (Qafter_change_functions, "after-change-functions");
+  DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
+
   /* The next one is initialized in init_buffer_once.  */
   staticpro (&Qucs_set_table_for_input);
 
-  Qkill_buffer_query_functions = intern_c_string ("kill-buffer-query-functions");
-  staticpro (&Qkill_buffer_query_functions);
-
   Fput (Qprotected_field, Qerror_conditions,
        pure_cons (Qprotected_field, pure_cons (Qerror, Qnil)));
   Fput (Qprotected_field, Qerror_message,
@@ -6096,8 +5979,15 @@ If any of them returns nil, the buffer is not killed.  */);
               doc: /* Normal hook run before changing the major mode of a buffer.
 The function `kill-all-local-variables' runs this before doing anything else.  */);
   Vchange_major_mode_hook = Qnil;
-  Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
-  staticpro (&Qchange_major_mode_hook);
+  DEFSYM (Qchange_major_mode_hook, "change-major-mode-hook");
+
+  DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
+              doc: /* Hook run when the buffer list changes.
+Functions running this hook are `get-buffer-create',
+`make-indirect-buffer', `rename-buffer', `kill-buffer',
+`record-buffer' and `unrecord-buffer'.  */);
+  Vbuffer_list_update_hook = Qnil;
+  DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
 
   defsubr (&Sbuffer_live_p);
   defsubr (&Sbuffer_list);
@@ -6120,12 +6010,11 @@ The function `kill-all-local-variables' runs this before doing anything else.  *
   defsubr (&Sother_buffer);
   defsubr (&Sbuffer_enable_undo);
   defsubr (&Skill_buffer);
+  defsubr (&Sbury_buffer_internal);
   defsubr (&Sset_buffer_major_mode);
-  defsubr (&Sswitch_to_buffer);
   defsubr (&Scurrent_buffer);
   defsubr (&Sset_buffer);
   defsubr (&Sbarf_if_buffer_read_only);
-  defsubr (&Sbury_buffer);
   defsubr (&Serase_buffer);
   defsubr (&Sbuffer_swap_text);
   defsubr (&Sset_buffer_multibyte);