[gnome-builder/gnome-builder-3-18] libide: avoid vfunc dereference when a sort vfunc is used



commit 570680c1b777af5c64bb5e3386d710b5d04a12a0
Author: Christian Hergert <christian hergert me>
Date:   Thu Oct 1 19:23:49 2015 -0700

    libide: avoid vfunc dereference when a sort vfunc is used
    
    We can avoid having to peek into the class structure by passing the
    function callback directly. Also, allow for static inlinining (although
    is suspect the optimizer will push this non-ideal code path as its own
    stack frame).

 libide/ide-completion-results.c |   39 ++++++++++++++++++++++++---------------
 1 files changed, 24 insertions(+), 15 deletions(-)
---
diff --git a/libide/ide-completion-results.c b/libide/ide-completion-results.c
index 2c7db8e..7e145b5 100644
--- a/libide/ide-completion-results.c
+++ b/libide/ide-completion-results.c
@@ -24,6 +24,7 @@
 
 #include "ide-completion-results.h"
 #include "ide-debug.h"
+#include "ide-list-inline.h"
 
 typedef struct
 {
@@ -74,6 +75,14 @@ typedef struct
   GList *head;
 } IdeCompletionResultsPrivate;
 
+typedef struct
+{
+  IdeCompletionResults *self;
+  gint (*compare) (IdeCompletionResults *,
+                   IdeCompletionItem *,
+                   IdeCompletionItem *);
+} SortState;
+
 G_DEFINE_TYPE_WITH_PRIVATE (IdeCompletionResults, ide_completion_results, G_TYPE_OBJECT)
 
 EGG_DEFINE_COUNTER (instances, "IdeCompletionResults", "Instances", "Number of IdeCompletionResults")
@@ -298,35 +307,35 @@ compare_fast (const IdeCompletionItem *left,
 
 
 static gint
-ide_completion_results_sorter (gconstpointer a,
-                               gconstpointer b,
-                               gpointer      user_data)
+sort_state_compare (gconstpointer a,
+                    gconstpointer b,
+                    gpointer      user_data)
 {
-  IdeCompletionResults *self = user_data;
+  SortState *state = user_data;
 
-  return IDE_COMPLETION_RESULTS_GET_CLASS (self)->compare (self, (gpointer)a, (gpointer)b);
+  return state->compare (state->self, (IdeCompletionItem *)a, (IdeCompletionItem *)b);
 }
 
 static void
 ide_completion_results_resort (IdeCompletionResults *self)
 {
   IdeCompletionResultsPrivate *priv = ide_completion_results_get_instance_private (self);
-  IdeCompletionResultsClass *klass;
-
-  g_assert (IDE_IS_COMPLETION_RESULTS (self));
-
-  klass = IDE_COMPLETION_RESULTS_GET_CLASS (self);
+  IdeCompletionResultsClass *klass = IDE_COMPLETION_RESULTS_GET_CLASS (self);
+  SortState state;
 
   /*
    * Instead of invoking the vfunc for every item, save ourself an extra
    * dereference and call g_list_sort() directly with our compare funcs.
-   *
-   * TODO: Next step would be to use an inline sort instead of g_list_sort.
    */
   if (G_LIKELY (klass->compare == NULL))
-    priv->head = g_list_sort (priv->head, (GCompareFunc)compare_fast);
-  else
-    priv->head = g_list_sort_with_data (priv->head, ide_completion_results_sorter, self);
+    {
+      priv->head = ide_list_sort (priv->head, (GCompareFunc)compare_fast);
+      return;
+    }
+
+  state.self = self;
+  state.compare = klass->compare;
+  priv->head = ide_list_sort_with_data (priv->head, sort_state_compare, &state);
 }
 
 void


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