emacs-diffs
[Top][All Lists]
Advanced

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

master 64044f545a: More behind the scenes transparent speedups around xs


From: Po Lu
Subject: master 64044f545a: More behind the scenes transparent speedups around xselect.c
Date: Fri, 2 Dec 2022 08:03:18 -0500 (EST)

branch: master
commit 64044f545add60e045ff16a9891b06f429ac935f
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    More behind the scenes transparent speedups around xselect.c
    
    * src/xdisp.c (display_menu_bar): Fix compiler warning about
    NULL pointer dereference.
    * src/xfns.c (Fx_begin_drag): Use x_intern_atoms.
    (Fx_change_window_property): Pass dpyinfo to
    x_fill_property_data.
    * src/xselect.c (lisp_data_to_selection_data): Use
    x_intern_atoms instead of syncing for each atom.
    (x_fill_property_data, x_send_client_event): Use
    x_intern_cached_atom.
    * src/xterm.c (x_intern_atoms): New function.
    * src/xterm.h: Update prototypes.
---
 src/xdisp.c   | 23 ++++++++++++++++-------
 src/xfns.c    |  6 +++---
 src/xselect.c | 32 +++++++++++++++++++++++++-------
 src/xterm.c   | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 src/xterm.h   | 16 +++++++---------
 5 files changed, 98 insertions(+), 26 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index 466bb1534a..b7333dc1ee 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -26312,13 +26312,17 @@ display_menu_bar (struct window *w)
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_PIXEL_WIDTH (f);
 #elif defined (HAVE_X_WINDOWS) /* X without toolkit.  */
-  struct window *menu_w;
+  struct window *menu_window;
+
+  menu_window = NULL;
+
   if (FRAME_WINDOW_P (f))
     {
       /* Menu bar lines are displayed in the desired matrix of the
         dummy window menu_bar_window.  */
-      menu_w = XWINDOW (f->menu_bar_window);
-      init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
+      menu_window = XWINDOW (f->menu_bar_window);
+      init_iterator (&it, menu_window, -1, -1,
+                    menu_window->desired_matrix->rows,
                     MENU_FACE_ID);
       it.first_visible_x = 0;
       it.last_visible_x = FRAME_PIXEL_WIDTH (f);
@@ -26379,11 +26383,16 @@ display_menu_bar (struct window *w)
 #if defined (HAVE_X_WINDOWS) && !defined (USE_X_TOOLKIT) && !defined (USE_GTK)
   /* With the non-toolkit version, modify the menu bar window height
      accordingly.  */
-  if (FRAME_WINDOW_P (it.f))
+  if (FRAME_WINDOW_P (it.f) && menu_window)
     {
-      struct glyph_row *row = it.glyph_row;
-      int delta_height = ((row->y + row->height)
-                         - WINDOW_BOX_HEIGHT_NO_MODE_LINE (menu_w));
+      struct glyph_row *row;
+      int delta_height;
+
+      row = it.glyph_row;
+      delta_height
+       = ((row->y + row->height)
+          - WINDOW_BOX_HEIGHT_NO_MODE_LINE (menu_window));
+
       if (delta_height != 0)
         {
          FRAME_MENU_BAR_HEIGHT (it.f) += delta_height;
diff --git a/src/xfns.c b/src/xfns.c
index 36b51a3011..df805d66db 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -7079,8 +7079,8 @@ that mouse buttons are being held down, such as 
immediately after a
   /* Catch errors since interning lots of targets can potentially
      generate a BadAlloc error.  */
   x_catch_errors (FRAME_X_DISPLAY (f));
-  XInternAtoms (FRAME_X_DISPLAY (f), target_names,
-               ntargets, False, target_atoms);
+  x_intern_atoms (FRAME_DISPLAY_INFO (f), target_names,
+                 ntargets, target_atoms);
   x_check_errors (FRAME_X_DISPLAY (f),
                  "Failed to intern target atoms: %s");
   x_uncatch_errors_after_check ();
@@ -7484,7 +7484,7 @@ silently ignored.  */)
       elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
       data = xnmalloc (nelements, elsize);
 
-      x_fill_property_data (FRAME_X_DISPLAY (f), value, data, nelements,
+      x_fill_property_data (FRAME_DISPLAY_INFO (f), value, data, nelements,
                             element_format);
     }
   else
diff --git a/src/xselect.c b/src/xselect.c
index c47093dfad..120a5a163e 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2216,7 +2216,12 @@ static void
 lisp_data_to_selection_data (struct x_display_info *dpyinfo,
                             Lisp_Object obj, struct selection_data *cs)
 {
-  Lisp_Object type = Qnil;
+  Lisp_Object type;
+  char **name_buffer;
+
+  USE_SAFE_ALLOCA;
+
+  type = Qnil;
 
   eassert (cs != NULL);
 
@@ -2321,8 +2326,19 @@ lisp_data_to_selection_data (struct x_display_info 
*dpyinfo,
          x_atoms = data;
          cs->format = 32;
          cs->size = size;
-         for (i = 0; i < size; i++)
-           x_atoms[i] = symbol_to_x_atom (dpyinfo, AREF (obj, i));
+
+         if (size == 1)
+           x_atoms[0] = symbol_to_x_atom (dpyinfo, AREF (obj, i));
+         else
+           {
+             SAFE_NALLOCA (name_buffer, sizeof *x_atoms, size);
+
+             for (i = 0; i < size; i++)
+               name_buffer[i] = SSDATA (SYMBOL_NAME (AREF (obj, i)));
+
+             x_intern_atoms (dpyinfo, name_buffer, size,
+                             x_atoms);
+           }
        }
       else
        /* This vector is an INTEGER set, or something like it */
@@ -2364,6 +2380,8 @@ lisp_data_to_selection_data (struct x_display_info 
*dpyinfo,
     signal_error (/* Qselection_error */ "Unrecognized selection data", obj);
 
   cs->type = symbol_to_x_atom (dpyinfo, type);
+
+  SAFE_FREE ();
 }
 
 static Lisp_Object
@@ -2891,8 +2909,8 @@ x_check_property_data (Lisp_Object data)
    XClientMessageEvent).  */
 
 void
-x_fill_property_data (Display *dpy, Lisp_Object data, void *ret,
-                     int nelements_max, int format)
+x_fill_property_data (struct x_display_info *dpyinfo, Lisp_Object data,
+                     void *ret, int nelements_max, int format)
 {
   unsigned long val;
   unsigned long  *d32 = (unsigned long  *) ret;
@@ -2927,7 +2945,7 @@ x_fill_property_data (Display *dpy, Lisp_Object data, 
void *ret,
       else if (STRINGP (o))
         {
           block_input ();
-          val = XInternAtom (dpy, SSDATA (o), False);
+          val = x_intern_cached_atom (dpyinfo, SSDATA (o), false);
           unblock_input ();
         }
       else
@@ -3215,7 +3233,7 @@ x_send_client_event (Lisp_Object display, Lisp_Object 
dest, Lisp_Object from,
 
   memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
   /* event.xclient.data can hold 20 chars, 10 shorts, or 5 longs.  */
-  x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
+  x_fill_property_data (dpyinfo, values, event.xclient.data.b,
                         5 * 32 / event.xclient.format,
                         event.xclient.format);
 
diff --git a/src/xterm.c b/src/xterm.c
index 43dc7c18b9..c775f19985 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -28875,6 +28875,53 @@ x_get_atom_name (struct x_display_info *dpyinfo, Atom 
atom,
   return value;
 }
 
+/* Intern an array of atoms, and do so quickly, avoiding extraneous
+   roundtrips to the X server.
+
+   Avoid sending atoms that have already been found to the X server.
+   This cannot do anything that will end up triggering garbage
+   collection.  */
+
+void
+x_intern_atoms (struct x_display_info *dpyinfo, char **names, int count,
+               Atom *atoms_return)
+{
+  int i, j, indices[256];
+  char *new_names[256];
+  Atom results[256], candidate;
+
+  if (count > 256)
+    /* Atoms array too big to inspect reasonably, just send it to the
+       server and back.  */
+    XInternAtoms (dpyinfo->display, new_names, count, False, atoms_return);
+  else
+    {
+      for (i = 0, j = 0; i < count; ++i)
+       {
+         candidate = x_intern_cached_atom (dpyinfo, names[i],
+                                           true);
+
+         if (candidate)
+           atoms_return[i] = candidate;
+         else
+           {
+             indices[j++] = i;
+             new_names[j - 1] = names[i];
+           }
+       }
+
+      if (!j)
+       return;
+
+      /* Now, get the results back from the X server.  */
+      XInternAtoms (dpyinfo->display, new_names, j, False,
+                   results);
+
+      for (i = 0; i < j; ++i)
+       atoms_return[indices[i]] = results[i];
+    }
+}
+
 #ifndef USE_GTK
 
 /* Set up XEmbed for F, and change its save set to handle the parent
diff --git a/src/xterm.h b/src/xterm.h
index 86763dc6e0..0b227cbdc0 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1723,6 +1723,11 @@ extern Lisp_Object x_handle_translate_coordinates 
(struct frame *, Lisp_Object,
 
 extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *,
                             int *, int *, int *, unsigned int *);
+extern Atom x_intern_cached_atom (struct x_display_info *, const char *,
+                                 bool);
+extern void x_intern_atoms (struct x_display_info *, char **, int, Atom *);
+extern char *x_get_atom_name (struct x_display_info *, Atom, bool *)
+  ATTRIBUTE_MALLOC ATTRIBUTE_DEALLOC_FREE;
 
 #ifdef HAVE_GTK3
 extern void x_scroll_bar_configure (GdkEvent *);
@@ -1815,11 +1820,8 @@ extern bool x_handle_dnd_message (struct frame *,
                                  struct input_event *,
                                  bool, int, int);
 extern int x_check_property_data (Lisp_Object);
-extern void x_fill_property_data (Display *,
-                                  Lisp_Object,
-                                  void *,
-                                 int,
-                                  int);
+extern void x_fill_property_data (struct x_display_info *, Lisp_Object,
+                                  void *, int, int);
 extern Lisp_Object x_property_data_to_lisp (struct frame *,
                                             const unsigned char *,
                                             Atom,
@@ -1832,10 +1834,6 @@ extern Lisp_Object x_timestamp_for_selection (struct 
x_display_info *,
                                              Lisp_Object);
 extern void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object,
                             Lisp_Object, Time);
-extern Atom x_intern_cached_atom (struct x_display_info *, const char *,
-                                 bool);
-extern char *x_get_atom_name (struct x_display_info *, Atom, bool *)
-  ATTRIBUTE_MALLOC ATTRIBUTE_DEALLOC_FREE;
 
 extern void mark_xselect (void);
 



reply via email to

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