emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r111073: * alloc.c (free_save_value):


From: Dmitry Antipov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r111073: * alloc.c (free_save_value): New function.
Date: Mon, 03 Dec 2012 12:06:02 +0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 111073
committer: Dmitry Antipov <address@hidden>
branch nick: trunk
timestamp: Mon 2012-12-03 12:06:02 +0400
message:
  * alloc.c (free_save_value): New function.
  (safe_alloca_unwind): Use it.
  * lisp.h (free_save_value): New prototype.
  * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value.
  Add comment.
  (save_excursion_restore): Adjust to match saved data structure.
  Use free_save_value to offload some work from GC.  Drop obsolete
  #if 0 code.
modified:
  src/ChangeLog
  src/alloc.c
  src/editfns.c
  src/lisp.h
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-12-03 01:08:31 +0000
+++ b/src/ChangeLog     2012-12-03 08:06:02 +0000
@@ -1,3 +1,14 @@
+2012-12-03  Dmitry Antipov  <address@hidden>
+
+       * alloc.c (free_save_value): New function.
+       (safe_alloca_unwind): Use it.
+       * lisp.h (free_save_value): New prototype.
+       * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value.
+       Add comment.
+       (save_excursion_restore): Adjust to match saved data structure.
+       Use free_save_value to offload some work from GC.  Drop obsolete
+       #if 0 code.
+
 2012-12-03  Chong Yidong  <address@hidden>
 
        * fileio.c (Vauto_save_list_file_name): Doc fix.

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2012-12-02 23:11:42 +0000
+++ b/src/alloc.c       2012-12-03 08:06:02 +0000
@@ -826,12 +826,7 @@
 Lisp_Object
 safe_alloca_unwind (Lisp_Object arg)
 {
-  register struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
-
-  p->dogc = 0;
-  xfree (p->pointer);
-  p->pointer = 0;
-  free_misc (arg);
+  free_save_value (arg);
   return Qnil;
 }
 
@@ -3365,6 +3360,19 @@
   return val;
 }
 
+/* Free a Lisp_Misc_Save_Value object.  */
+
+void
+free_save_value (Lisp_Object save)
+{
+  register struct Lisp_Save_Value *p = XSAVE_VALUE (save);
+
+  p->dogc = 0;
+  xfree (p->pointer);
+  p->pointer = NULL;
+  free_misc (save);
+}
+
 /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST.  */
 
 Lisp_Object

=== modified file 'src/editfns.c'
--- a/src/editfns.c     2012-11-16 02:40:54 +0000
+++ b/src/editfns.c     2012-12-03 08:06:02 +0000
@@ -813,38 +813,43 @@
                              Qnil, Qt, Qnil);
 }
 
-
+/* Save current buffer state for `save-excursion' special form.
+   We (ab)use Lisp_Misc_Save_Value to allow explicit free and so
+   offload some work from GC.  */
+
 Lisp_Object
 save_excursion_save (void)
 {
-  bool visible = (XBUFFER (XWINDOW (selected_window)->buffer)
-                 == current_buffer);
+  Lisp_Object save, *data = xmalloc (word_size * 4);
+
+  data[0] = Fpoint_marker ();
   /* Do not copy the mark if it points to nowhere.  */
-  Lisp_Object mark = (XMARKER (BVAR (current_buffer, mark))->buffer
-                     ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
-                     : Qnil);
+  data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer
+            ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
+            : Qnil);
+  /* Selected window if current buffer is shown in it, nil otherwise.  */
+  data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
+            ? selected_window : Qnil);
+  data[3] = BVAR (current_buffer, mark_active);
 
-  return Fcons (Fpoint_marker (),
-               Fcons (mark,
-                      Fcons (visible ? Qt : Qnil,
-                             Fcons (BVAR (current_buffer, mark_active),
-                                    selected_window))));
+  save = make_save_value (data, 4);
+  XSAVE_VALUE (save)->dogc = 1;
+  return save;
 }
 
+/* Restore saved buffer before leaving `save-excursion' special form.  */
+
 Lisp_Object
 save_excursion_restore (Lisp_Object info)
 {
-  Lisp_Object tem, tem1, omark, nmark;
+  Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer;
   struct gcpro gcpro1, gcpro2, gcpro3;
-  bool visible_p;
 
-  tem = Fmarker_buffer (XCAR (info));
-  /* If buffer being returned to is now deleted, avoid error */
-  /* Otherwise could get error here while unwinding to top level
-     and crash */
-  /* In that case, Fmarker_buffer returns nil now.  */
+  tem = Fmarker_buffer (data[0]);
+  /* If we're unwinding to top level, saved buffer may be deleted.  This
+     means that all of its markers are unchained and so tem is nil.  */
   if (NILP (tem))
-    return Qnil;
+    goto out;
 
   omark = nmark = Qnil;
   GCPRO3 (info, omark, nmark);
@@ -852,13 +857,12 @@
   Fset_buffer (tem);
 
   /* Point marker.  */
-  tem = XCAR (info);
+  tem = data[0];
   Fgoto_char (tem);
   unchain_marker (XMARKER (tem));
 
   /* Mark marker.  */
-  info = XCDR (info);
-  tem = XCAR (info);
+  tem = data[1];
   omark = Fmarker_position (BVAR (current_buffer, mark));
   if (NILP (tem))
     unchain_marker (XMARKER (BVAR (current_buffer, mark)));
@@ -869,23 +873,8 @@
       unchain_marker (XMARKER (tem));
     }
 
-  /* visible */
-  info = XCDR (info);
-  visible_p = !NILP (XCAR (info));
-
-#if 0 /* We used to make the current buffer visible in the selected window
-        if that was true previously.  That avoids some anomalies.
-        But it creates others, and it wasn't documented, and it is simpler
-        and cleaner never to alter the window/buffer connections.  */
-  tem1 = Fcar (tem);
-  if (!NILP (tem1)
-      && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
-    Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
-#endif /* 0 */
-
-  /* Mark active */
-  info = XCDR (info);
-  tem = XCAR (info);
+  /* Mark active.  */
+  tem = data[3];
   tem1 = BVAR (current_buffer, mark_active);
   bset_mark_active (current_buffer, tem);
 
@@ -909,8 +898,8 @@
   /* If buffer was visible in a window, and a different window was
      selected, and the old selected window is still showing this
      buffer, restore point in that window.  */
-  tem = XCDR (info);
-  if (visible_p
+  tem = data[2];
+  if (WINDOWP (tem)
       && !EQ (tem, selected_window)
       && (tem1 = XWINDOW (tem)->buffer,
          (/* Window is live...  */
@@ -920,6 +909,10 @@
     Fset_window_point (tem, make_number (PT));
 
   UNGCPRO;
+
+ out:
+
+  free_save_value (info);
   return Qnil;
 }
 

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2012-11-22 09:32:32 +0000
+++ b/src/lisp.h        2012-12-03 08:06:02 +0000
@@ -2963,6 +2963,7 @@
 extern void display_malloc_warning (void);
 extern ptrdiff_t inhibit_garbage_collection (void);
 extern Lisp_Object make_save_value (void *, ptrdiff_t);
+extern void free_save_value (Lisp_Object);
 extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
 extern void free_marker (Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);


reply via email to

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