[gtk+] GtkTextView: use GSlice to allocate GtkTextLineSegment's



commit 983a03d5f85f4e10f5392df2fd2de0c0bf670f7d
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Fri Apr 11 17:45:50 2014 +0200

    GtkTextView: use GSlice to allocate GtkTextLineSegment's
    
    Use GSlice to allocate all types of segments:
    - char
    - toggle
    - mark
    - pixbuf
    - child widget
    
    Char segments are a bit more complicated because the length of the text
    is determined at run time and stored in the 'byte_count' field. If the
    text is long, GSlice will call the system malloc() anyway, so it's
    better to always use GSlice for GtkTextLineSegment.
    
    Toggle segments are also freed in gtktextbtree.c, hence the function
    _gtk_toggle_segment_free() (for a later commit it would be nice to
    rename those functions with the _gtk_text prefix).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=727908

 gtk/gtktextbtree.c   |    7 ++++---
 gtk/gtktextchild.c   |   22 +++++++++++-----------
 gtk/gtktextmark.c    |   17 +++++++----------
 gtk/gtktextsegment.c |   43 +++++++++++++++++++++++++++++++++----------
 gtk/gtktextsegment.h |    1 +
 5 files changed, 56 insertions(+), 34 deletions(-)
---
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index a7c86c5..825eb95 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -65,6 +65,7 @@
 #include "gtktextiterprivate.h"
 #include "gtkdebug.h"
 #include "gtktextmarkprivate.h"
+#include "gtktextsegment.h"
 
 /*
  * Types
@@ -901,9 +902,9 @@ _gtk_text_btree_delete (GtkTextIter *start,
               * cleanup_line() below. See bug 317125.
               */
              next2 = prev_seg->next->next;
-             g_free ((char *)prev_seg->next);
+              _gtk_toggle_segment_free (prev_seg->next);
              prev_seg->next = next2;
-             g_free ((char *)seg);
+              _gtk_toggle_segment_free (seg);
              seg = NULL;
            }
          else
@@ -1952,7 +1953,7 @@ _gtk_text_btree_tag (const GtkTextIter *start_orig,
           seg->body.toggle.inNodeCounts = FALSE;
         }
 
-      g_free (seg);
+      _gtk_toggle_segment_free (seg);
 
       /* We only clean up lines when we're done with them, saves some
          gratuitous line-segment-traversals */
diff --git a/gtk/gtktextchild.c b/gtk/gtktextchild.c
index de609d4..96e7ffd 100644
--- a/gtk/gtktextchild.c
+++ b/gtk/gtktextchild.c
@@ -73,6 +73,12 @@
       }                                                                 \
   } G_STMT_END
 
+#define PIXBUF_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
+        + sizeof (GtkTextPixbuf)))
+
+#define WIDGET_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
+        + sizeof (GtkTextChildBody)))
+
 static GtkTextLineSegment *
 pixbuf_segment_cleanup_func (GtkTextLineSegment *seg,
                              GtkTextLine        *line)
@@ -89,7 +95,7 @@ pixbuf_segment_delete_func (GtkTextLineSegment *seg,
   if (seg->body.pixbuf.pixbuf)
     g_object_unref (seg->body.pixbuf.pixbuf);
 
-  g_free (seg);
+  g_slice_free1 (PIXBUF_SEG_SIZE, seg);
 
   return 0;
 }
@@ -120,15 +126,12 @@ const GtkTextLineSegmentClass gtk_text_pixbuf_type = {
 
 };
 
-#define PIXBUF_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
-        + sizeof (GtkTextPixbuf)))
-
 GtkTextLineSegment *
 _gtk_pixbuf_segment_new (GdkPixbuf *pixbuf)
 {
   GtkTextLineSegment *seg;
 
-  seg = g_malloc (PIXBUF_SEG_SIZE);
+  seg = g_slice_alloc (PIXBUF_SEG_SIZE);
 
   seg->type = &gtk_text_pixbuf_type;
 
@@ -218,15 +221,12 @@ const GtkTextLineSegmentClass gtk_text_child_type = {
   child_segment_check_func                               /* checkFunc */
 };
 
-#define WIDGET_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
-        + sizeof (GtkTextChildBody)))
-
 GtkTextLineSegment *
 _gtk_widget_segment_new (GtkTextChildAnchor *anchor)
 {
   GtkTextLineSegment *seg;
 
-  seg = g_malloc (WIDGET_SEG_SIZE);
+  seg = g_slice_alloc (WIDGET_SEG_SIZE);
 
   seg->type = &gtk_text_child_type;
 
@@ -370,8 +370,8 @@ gtk_text_child_anchor_finalize (GObject *obj)
         }
   
       g_slist_free (seg->body.child.widgets);
-  
-      g_free (seg);
+
+      g_slice_free1 (WIDGET_SEG_SIZE, seg);
     }
 
   anchor->segment = NULL;
diff --git a/gtk/gtktextmark.c b/gtk/gtktextmark.c
index 7a1b7e3..d79e532 100644
--- a/gtk/gtktextmark.c
+++ b/gtk/gtktextmark.c
@@ -90,6 +90,11 @@
  * Marks are typically created using the gtk_text_buffer_create_mark() function.
  */
 
+/*
+ * Macro that determines the size of a mark segment:
+ */
+#define MSEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
+        + sizeof (GtkTextMarkBody)))
 
 static void gtk_text_mark_set_property (GObject         *object,
                                        guint            prop_id,
@@ -161,7 +166,7 @@ gtk_text_mark_finalize (GObject *obj)
                    "impending");
 
       g_free (seg->body.mark.name);
-      g_free (seg);
+      g_slice_free1 (MSEG_SIZE, seg);
 
       mark->segment = NULL;
     }
@@ -358,20 +363,12 @@ gtk_text_mark_get_left_gravity (GtkTextMark *mark)
   return seg->type == &gtk_text_left_mark_type;
 }
 
-/*
- * Macro that determines the size of a mark segment:
- */
-
-#define MSEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
-        + sizeof (GtkTextMarkBody)))
-
-
 static GtkTextLineSegment *
 gtk_mark_segment_new (GtkTextMark *mark_obj)
 {
   GtkTextLineSegment *mark;
 
-  mark = (GtkTextLineSegment *) g_malloc0 (MSEG_SIZE);
+  mark = g_slice_alloc0 (MSEG_SIZE);
   mark->body.mark.name = NULL;
   mark->type = &gtk_text_right_mark_type;
 
diff --git a/gtk/gtktextsegment.c b/gtk/gtktextsegment.c
index c815262..beb92cf 100644
--- a/gtk/gtktextsegment.c
+++ b/gtk/gtktextsegment.c
@@ -194,7 +194,7 @@ _gtk_char_segment_new (const gchar *text, guint len)
 
   g_assert (gtk_text_byte_begins_utf8_char (text));
 
-  seg = g_malloc (CSEG_SIZE (len));
+  seg = g_slice_alloc (CSEG_SIZE (len));
   seg->type = (GtkTextLineSegmentClass *)&gtk_text_char_type;
   seg->next = NULL;
   seg->byte_count = len;
@@ -222,7 +222,7 @@ _gtk_char_segment_new_from_two_strings (const gchar *text1,
   g_assert (gtk_text_byte_begins_utf8_char (text1));
   g_assert (gtk_text_byte_begins_utf8_char (text2));
 
-  seg = g_malloc (CSEG_SIZE (len1+len2));
+  seg = g_slice_alloc (CSEG_SIZE (len1+len2));
   seg->type = &gtk_text_char_type;
   seg->next = NULL;
   seg->byte_count = len1 + len2;
@@ -238,6 +238,17 @@ _gtk_char_segment_new_from_two_strings (const gchar *text1,
   return seg;
 }
 
+static void
+_gtk_char_segment_free (GtkTextLineSegment *seg)
+{
+  if (seg == NULL)
+    return;
+
+  g_assert (seg->type == &gtk_text_char_type);
+
+  g_slice_free1 (CSEG_SIZE (seg->byte_count), seg);
+}
+
 /*
  *--------------------------------------------------------------
  *
@@ -285,7 +296,7 @@ char_segment_split_func (GtkTextLineSegment *seg, int index)
       char_segment_self_check (new2);
     }
 
-  g_free (seg);
+  _gtk_char_segment_free (seg);
   return new1;
 }
 
@@ -340,8 +351,8 @@ char_segment_cleanup_func (GtkTextLineSegment *segPtr, GtkTextLine *line)
   if (gtk_get_debug_flags () & GTK_DEBUG_TEXT)
     char_segment_self_check (newPtr);
 
-  g_free (segPtr);
-  g_free (segPtr2);
+  _gtk_char_segment_free (segPtr);
+  _gtk_char_segment_free (segPtr2);
   return newPtr;
 }
 
@@ -371,7 +382,7 @@ char_segment_cleanup_func (GtkTextLineSegment *segPtr, GtkTextLine *line)
 static int
 char_segment_delete_func (GtkTextLineSegment *segPtr, GtkTextLine *line, int treeGone)
 {
-  g_free ((char*) segPtr);
+  _gtk_char_segment_free (segPtr);
   return 0;
 }
 
@@ -417,7 +428,7 @@ _gtk_toggle_segment_new (GtkTextTagInfo *info, gboolean on)
 {
   GtkTextLineSegment *seg;
 
-  seg = g_malloc (TSEG_SIZE);
+  seg = g_slice_alloc (TSEG_SIZE);
 
   seg->type = on ? &gtk_text_toggle_on_type : &gtk_text_toggle_off_type;
 
@@ -432,6 +443,18 @@ _gtk_toggle_segment_new (GtkTextTagInfo *info, gboolean on)
   return seg;
 }
 
+void
+_gtk_toggle_segment_free (GtkTextLineSegment *seg)
+{
+  if (seg == NULL)
+    return;
+
+  g_assert (seg->type == &gtk_text_toggle_on_type ||
+            seg->type == &gtk_text_toggle_off_type);
+
+  g_slice_free1 (TSEG_SIZE, seg);
+}
+
 /*
  *--------------------------------------------------------------
  *
@@ -462,7 +485,7 @@ toggle_segment_delete_func (GtkTextLineSegment *segPtr, GtkTextLine *line, int t
 {
   if (treeGone)
     {
-      g_free ((char *) segPtr);
+      _gtk_toggle_segment_free (segPtr);
       return 0;
     }
 
@@ -545,9 +568,9 @@ toggle_segment_cleanup_func (GtkTextLineSegment *segPtr, GtkTextLine *line)
                                              segPtr->body.toggle.info, -counts);
             }
           prevPtr->next = segPtr2->next;
-          g_free ((char *) segPtr2);
+          _gtk_toggle_segment_free (segPtr2);
           segPtr2 = segPtr->next;
-          g_free ((char *) segPtr);
+          _gtk_toggle_segment_free (segPtr);
           return segPtr2;
         }
     }
diff --git a/gtk/gtktextsegment.h b/gtk/gtktextsegment.h
index ea5f904..5621bde 100644
--- a/gtk/gtktextsegment.h
+++ b/gtk/gtktextsegment.h
@@ -164,6 +164,7 @@ GtkTextLineSegment *_gtk_char_segment_new_from_two_strings (const gchar    *text
 GtkTextLineSegment *_gtk_toggle_segment_new                (GtkTextTagInfo *info,
                                                             gboolean        on);
 
+void                _gtk_toggle_segment_free               (GtkTextLineSegment *seg);
 
 G_END_DECLS
 


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