Skip to content

Commit

Permalink
GtkTextView: use GSlice to allocate GtkTextLineSegment's
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Sébastien Wilmet authored and Matthias Clasen committed Apr 13, 2014
1 parent d69d57a commit 983a03d
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 34 deletions.
7 changes: 4 additions & 3 deletions gtk/gtktextbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "gtktextiterprivate.h"
#include "gtkdebug.h"
#include "gtktextmarkprivate.h"
#include "gtktextsegment.h"

/*
* Types
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
22 changes: 11 additions & 11 deletions gtk/gtktextchild.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
17 changes: 7 additions & 10 deletions gtk/gtktextmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down
43 changes: 33 additions & 10 deletions gtk/gtktextsegment.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}

/*
*--------------------------------------------------------------
*
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand All @@ -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);
}

/*
*--------------------------------------------------------------
*
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
}
Expand Down
1 change: 1 addition & 0 deletions gtk/gtktextsegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 983a03d

Please sign in to comment.