mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 10:08:56 +01:00 
			
		
		
		
	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:
		@@ -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		\
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								gobject/gtype-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								gobject/gtype-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -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 <glib-object.h> 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__ */
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user