From: Benjamin Otte Date: Wed, 20 Jan 2010 20:06:30 +0000 (+0100) Subject: Move the boxed private type data to TypeNode X-Git-Tag: 2.23.2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=11d4e59712b5a19c9847facf6da79946c9bd24aa;p=platform%2Fupstream%2Fglib.git Move the boxed private type data to TypeNode This way we don't need to keep a custom array that we bsearch on (and that isn't threadsafe) but can use the gtype.c machinery that is threadsafe. And fast, too! https://bugzilla.gnome.org/show_bug.cgi?id=554887 --- diff --git a/gobject/Makefile.am b/gobject/Makefile.am index 7579dc935..928c61670 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -114,7 +114,10 @@ gobject_public_h_sources = \ gmarshal.h # GObject library header files that don't get installed -gobject_private_h_sources = gatomicarray.h +gobject_private_h_sources = \ + gatomicarray.h \ + gtype-private.h + # GObject library C sources to build the library from gobject_c_sources = \ gatomicarray.c \ diff --git a/gobject/gboxed.c b/gobject/gboxed.c index f1cad90eb..4425b3b64 100644 --- a/gobject/gboxed.c +++ b/gobject/gboxed.c @@ -22,7 +22,7 @@ #include #include "gboxed.h" -#include "gbsearcharray.h" +#include "gtype-private.h" #include "gvalue.h" #include "gvaluearray.h" #include "gclosure.h" @@ -46,39 +46,6 @@ * based libraries. */ -/* --- typedefs & structures --- */ -typedef struct -{ - GType type; - GBoxedCopyFunc copy; - GBoxedFreeFunc free; -} BoxedNode; - - -/* --- prototypes --- */ -static gint boxed_nodes_cmp (gconstpointer p1, - gconstpointer p2); - - -/* --- variables --- */ -static GBSearchArray *boxed_bsa = NULL; -static const GBSearchConfig boxed_bconfig = { - sizeof (BoxedNode), - boxed_nodes_cmp, - 0, -}; - - -/* --- functions --- */ -static gint -boxed_nodes_cmp (gconstpointer p1, - gconstpointer p2) -{ - const BoxedNode *node1 = p1, *node2 = p2; - - return G_BSEARCH_ARRAY_CMP (node1->type, node2->type); -} - static inline void /* keep this function in sync with gvalue.c */ value_meminit (GValue *value, GType value_type) @@ -129,8 +96,6 @@ g_boxed_type_init (void) const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, }; GType type; - boxed_bsa = g_bsearch_array_create (&boxed_bconfig); - /* G_TYPE_BOXED */ type = g_type_register_fundamental (G_TYPE_BOXED, g_intern_static_string ("GBoxed"), &info, &finfo, @@ -307,26 +272,6 @@ g_byte_array_get_type (void) return type_id; } -static gpointer -_g_type_boxed_copy (GType type, gconstpointer value) -{ - BoxedNode key, *node; - - key.type = G_VALUE_TYPE (value); - node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key); - return node->copy (value); -} - -static void -_g_type_boxed_free (GType type, gpointer value) -{ - BoxedNode key, *node; - - key.type = G_VALUE_TYPE (value); - node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key); - node->free (value); -} - static void boxed_proxy_value_init (GValue *value) { @@ -426,7 +371,7 @@ g_boxed_type_register_static (const gchar *name, "p", boxed_proxy_lcopy_value, }; - static const GTypeInfo type_info = { + GTypeInfo type_info = { 0, /* class_size */ NULL, /* base_init */ NULL, /* base_finalize */ @@ -449,14 +394,7 @@ g_boxed_type_register_static (const gchar *name, /* install proxy functions upon successfull registration */ if (type) - { - BoxedNode key; - - key.type = type; - key.copy = boxed_copy; - key.free = boxed_free; - boxed_bsa = g_bsearch_array_insert (boxed_bsa, &boxed_bconfig, &key); - } + _g_type_boxed_init (type, boxed_copy, boxed_free); return type; } @@ -487,7 +425,7 @@ g_boxed_copy (GType boxed_type, /* check if our proxying implementation is used, we can short-cut here */ if (value_table->value_copy == boxed_proxy_value_copy) - dest_boxed = _g_type_boxed_copy (boxed_type, src_boxed); + dest_boxed = _g_type_boxed_copy (boxed_type, (gpointer) src_boxed); else { GValue src_value, dest_value; @@ -614,7 +552,7 @@ value_set_boxed_internal (GValue *value, if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer); value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS; - value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : (gconstpointer) boxed; + value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : (gpointer) boxed; } /** diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h new file mode 100644 index 000000000..664eb55c3 --- /dev/null +++ b/gobject/gtype-private.h @@ -0,0 +1,41 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TYPE_PRIVATE_H__ +#define __G_TYPE_PRIVATE_H__ + +#include "gboxed.h" + +G_BEGIN_DECLS + +/* for gboxed.c */ +gpointer _g_type_boxed_copy (GType type, + gpointer value); +void _g_type_boxed_free (GType type, + gpointer value); +void _g_type_boxed_init (GType type, + GBoxedCopyFunc copy_func, + GBoxedFreeFunc free_func); + +G_END_DECLS + +#endif /* __G_TYPE_PRIVATE_H__ */ diff --git a/gobject/gtype.c b/gobject/gtype.c index 424861e6d..f49c8d048 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -26,6 +26,7 @@ #include #include "gtype.h" +#include "gtype-private.h" #include "gtypeplugin.h" #include "gvaluecollector.h" #include "gbsearcharray.h" @@ -168,6 +169,7 @@ /* --- typedefs --- */ typedef struct _TypeNode TypeNode; typedef struct _CommonData CommonData; +typedef struct _BoxedData BoxedData; typedef struct _IFaceData IFaceData; typedef struct _ClassData ClassData; typedef struct _InstanceData InstanceData; @@ -253,6 +255,7 @@ struct _TypeNode #define NODE_FUNDAMENTAL_TYPE(node) (node->supers[node->n_supers]) #define NODE_NAME(node) (g_quark_to_string (node->qname)) #define NODE_REFCOUNT(node) ((guint) g_atomic_int_get ((int *) &(node)->ref_count)) +#define NODE_IS_BOXED(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED) #define NODE_IS_IFACE(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE) #define CLASSED_NODE_IFACES_ENTRIES(node) (&(node)->_prot.iface_entries) #define CLASSED_NODE_IFACES_ENTRIES_LOCKED(node)(G_ATOMIC_ARRAY_GET_LOCKED(CLASSED_NODE_IFACES_ENTRIES((node)), IFaceEntries)) @@ -296,6 +299,13 @@ struct _CommonData GTypeValueTable *value_table; }; +struct _BoxedData +{ + CommonData data; + GBoxedCopyFunc copy_func; + GBoxedFreeFunc free_func; +}; + struct _IFaceData { CommonData common; @@ -342,6 +352,7 @@ struct _InstanceData union _TypeData { CommonData common; + BoxedData boxed; IFaceData iface; ClassData class; InstanceData instance; @@ -1120,6 +1131,12 @@ type_data_make_W (TypeNode *node, data->iface.dflt_data = info->class_data; data->iface.dflt_vtable = NULL; } + else if (NODE_IS_BOXED (node)) + { + data = g_malloc0 (sizeof (BoxedData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (BoxedData)); + } else { data = g_malloc0 (sizeof (CommonData) + vtable_size); @@ -4164,6 +4181,34 @@ g_type_name_from_class (GTypeClass *g_class) } +/* --- private api for gboxed.c --- */ +gpointer +_g_type_boxed_copy (GType type, gpointer value) +{ + TypeNode *node = lookup_type_node_I (type); + + return node->data->boxed.copy_func (value); +} + +void +_g_type_boxed_free (GType type, gpointer value) +{ + TypeNode *node = lookup_type_node_I (type); + + node->data->boxed.free_func (value); +} + +void +_g_type_boxed_init (GType type, + GBoxedCopyFunc copy_func, + GBoxedFreeFunc free_func) +{ + TypeNode *node = lookup_type_node_I (type); + + node->data->boxed.copy_func = copy_func; + node->data->boxed.free_func = free_func; +} + /* --- initialization --- */ /** * g_type_init_with_debug_flags: