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
This commit is contained in:
Benjamin Otte
2010-01-20 21:06:30 +01:00
parent ac666d2ae3
commit 11d4e59712
4 changed files with 95 additions and 68 deletions

View File

@@ -26,6 +26,7 @@
#include <string.h>
#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: