Fix a typo
[platform/upstream/glib.git] / gobject / gtype.c
index 412e9cc..dac5e8f 100644 (file)
 #include <string.h>
 
 #include "gtype.h"
+#include "gtype-private.h"
 #include "gtypeplugin.h"
 #include "gvaluecollector.h"
 #include "gbsearcharray.h"
-#include "gobjectalias.h"
 #include "gatomicarray.h"
+#include "gobject_trace.h"
 
 
 /**
     else \
       g_error ("%s()%s`%s'", _fname, _action, _tname); \
 }G_STMT_END
-#define        g_return_val_if_uninitialized(condition, init_function, return_value) G_STMT_START{     \
-  if (!(condition))                                                                            \
-    {                                                                                          \
-      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,                                               \
-            "%s: initialization assertion failed, use %s() prior to this function",            \
-            G_STRLOC, G_STRINGIFY (init_function));                                            \
-      return (return_value);                                                                   \
-    }                                                                                          \
+#define g_return_val_if_type_system_uninitialized(return_value) G_STMT_START{ \
+    if (G_UNLIKELY (!static_quark_type_flags))                                \
+      {                                                                       \
+        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,                            \
+               "%s: You forgot to call g_type_init()",                        \
+               G_STRLOC);                                                     \
+        return (return_value);                                                \
+      }                                                                       \
 }G_STMT_END
 
 #ifdef  G_ENABLE_DEBUG
 /* --- 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;
@@ -228,7 +230,7 @@ struct _TypeNode
   GTypePlugin *plugin;
   guint        n_children; /* writable with lock */
   guint        n_supers : 8;
-  guint        _prot_n_prerequisites : 9;
+  guint        n_prerequisites : 9;
   guint        is_classed : 1;
   guint        is_instantiatable : 1;
   guint        mutatable_check_cache : 1;      /* combines some common path checks */
@@ -238,8 +240,9 @@ struct _TypeNode
   GData       *global_gdata;
   union {
     GAtomicArray iface_entries;                /* for !iface types */
-    GType       *prerequisistes;
+    GAtomicArray offsets;
   } _prot;
+  GType       *prerequisites;
   GType        supers[1]; /* flexible array */
 };
 
@@ -253,11 +256,12 @@ 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))
-#define        IFACE_NODE_N_PREREQUISITES(node)        ((node)->_prot_n_prerequisites)
-#define        IFACE_NODE_PREREQUISITES(node)          ((node)->_prot.prerequisistes)
+#define        IFACE_NODE_N_PREREQUISITES(node)        ((node)->n_prerequisites)
+#define        IFACE_NODE_PREREQUISITES(node)          ((node)->prerequisites)
 #define        iface_node_get_holders_L(node)          ((IFaceHolder*) type_get_qdata_L ((node), static_quark_iface_holder))
 #define        iface_node_set_holders_W(node, holders) (type_set_qdata_W ((node), static_quark_iface_holder, (holders)))
 #define        iface_node_get_dependants_array_L(n)    ((GType*) type_get_qdata_L ((n), static_quark_dependants_array))
@@ -296,6 +300,13 @@ struct _CommonData
   GTypeValueTable  *value_table;
 };
 
+struct _BoxedData
+{
+  CommonData         data;
+  GBoxedCopyFunc     copy_func;
+  GBoxedFreeFunc     free_func;
+};
+
 struct _IFaceData
 {
   CommonData         common;
@@ -306,13 +317,13 @@ struct _IFaceData
   GClassFinalizeFunc dflt_finalize;
   gconstpointer      dflt_data;
   gpointer           dflt_vtable;
-  GAtomicArray       offsets;
 };
 
 struct _ClassData
 {
   CommonData         common;
   guint16            class_size;
+  guint16            class_private_size;
   int volatile       init_state; /* atomic - g_type_class_ref reads it unlocked */
   GBaseInitFunc      class_init_base;
   GBaseFinalizeFunc  class_finalize_base;
@@ -326,6 +337,7 @@ struct _InstanceData
 {
   CommonData         common;
   guint16            class_size;
+  guint16            class_private_size;
   int volatile       init_state; /* atomic - g_type_class_ref reads it unlocked */
   GBaseInitFunc      class_init_base;
   GBaseFinalizeFunc  class_finalize_base;
@@ -342,6 +354,7 @@ struct _InstanceData
 union _TypeData
 {
   CommonData         common;
+  BoxedData          boxed;
   IFaceData          iface;
   ClassData          class;
   InstanceData       instance;
@@ -468,7 +481,9 @@ type_node_any_new_W (TypeNode             *pnode,
       pnode->children = g_renew (GType, pnode->children, pnode->n_children);
       pnode->children[i] = type;
     }
-  
+
+  TRACE(GOBJECT_TYPE_NEW(name, node->supers[1], type));
+
   node->plugin = plugin;
   node->n_children = 0;
   node->children = NULL;
@@ -544,7 +559,7 @@ lookup_iface_entry_I (volatile IFaceEntries *entries,
     return NULL;
 
   G_ATOMIC_ARRAY_DO_TRANSACTION
-    (&iface_node->data->iface.offsets, guint8,
+    (&iface_node->_prot.offsets, guint8,
 
      entry = NULL;
      offsets = transaction_data;
@@ -1070,6 +1085,8 @@ type_data_make_W (TypeNode              *node,
    
   if (node->is_instantiatable) /* carefull, is_instantiatable is also is_classed */
     {
+      TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
+
       data = g_malloc0 (sizeof (InstanceData) + vtable_size);
       if (vtable_size)
        vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData));
@@ -1086,6 +1103,9 @@ type_data_make_W (TypeNode              *node,
        * after the parent class has been initialized
        */
       data->instance.private_size = 0;
+      data->instance.class_private_size = 0;
+      if (pnode)
+        data->instance.class_private_size = pnode->data->instance.class_private_size;
 #ifdef DISABLE_MEM_POOLS
       data->instance.n_preallocs = 0;
 #else  /* !DISABLE_MEM_POOLS */
@@ -1095,6 +1115,8 @@ type_data_make_W (TypeNode              *node,
     }
   else if (node->is_classed) /* only classed */
     {
+      TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
+
       data = g_malloc0 (sizeof (ClassData) + vtable_size);
       if (vtable_size)
        vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData));
@@ -1105,6 +1127,9 @@ type_data_make_W (TypeNode              *node,
       data->class.class_finalize = info->class_finalize;
       data->class.class_data = info->class_data;
       data->class.class = NULL;
+      data->class.class_private_size = 0;
+      if (pnode)
+        data->class.class_private_size = pnode->data->class.class_private_size;
       data->class.init_state = UNINITIALIZED;
     }
   else if (NODE_IS_IFACE (node))
@@ -1120,6 +1145,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);
@@ -1225,7 +1256,7 @@ iface_node_has_available_offset_L (TypeNode *iface_node,
 {
   guint8 *offsets;
 
-  offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->data->iface.offsets, guint8);
+  offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8);
   if (offsets == NULL)
     return TRUE;
 
@@ -1276,7 +1307,7 @@ iface_node_set_offset_L (TypeNode *iface_node,
   int new_size, old_size;
   int i;
 
-  old_offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->data->iface.offsets, guint8);
+  old_offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8);
   if (old_offsets == NULL)
     old_size = 0;
   else
@@ -1288,7 +1319,7 @@ iface_node_set_offset_L (TypeNode *iface_node,
     }
   new_size = MAX (old_size, offset + 1);
 
-  offsets = _g_atomic_array_copy (&iface_node->data->iface.offsets,
+  offsets = _g_atomic_array_copy (&iface_node->_prot.offsets,
                                  0, new_size - old_size);
 
   /* Mark new area as unused */
@@ -1297,7 +1328,7 @@ iface_node_set_offset_L (TypeNode *iface_node,
 
   offsets[offset] = index + 1;
 
-  _g_atomic_array_update (&iface_node->data->iface.offsets, offsets);
+  _g_atomic_array_update (&iface_node->_prot.offsets, offsets);
 }
 
 static void
@@ -1575,14 +1606,16 @@ g_type_interface_add_prerequisite (GType interface_type,
 /**
  * g_type_interface_prerequisites:
  * @interface_type: an interface type
- * @n_prerequisites: location to return the number of prerequisites, or %NULL
+ * @n_prerequisites: (out) (allow-none): location to return the number
+ *                   of prerequisites, or %NULL
  *
  * Returns the prerequisites of an interfaces type.
  *
  * Since: 2.2
  *
- * Returns: a newly-allocated zero-terminated array of #GType containing
- *  the prerequisites of @interface_type
+ * Returns: (array length=n_prerequisites) (transfer full): a
+ *          newly-allocated zero-terminated array of #GType containing
+ *          the prerequisites of @interface_type
  */
 GType*
 g_type_interface_prerequisites (GType  interface_type,
@@ -1605,9 +1638,11 @@ g_type_interface_prerequisites (GType  interface_type,
        {
          GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
          TypeNode *node = lookup_type_node_I (prerequisite);
-         if (node->is_instantiatable &&
-             (!inode || type_node_is_a_L (node, inode)))
-           inode = node;
+         if (node->is_instantiatable)
+            {
+              if (!inode || type_node_is_a_L (node, inode))
+               inode = node;
+            }
          else
            types[n++] = NODE_TYPE (node);
        }
@@ -1785,7 +1820,7 @@ instance_real_class_get (gpointer instance)
 }
 
 /**
- * g_type_create_instance:
+ * g_type_create_instance: (skip)
  * @type: An instantiatable type to create an instance for.
  *
  * Creates and initializes an instance of @type if @type is valid and
@@ -1852,7 +1887,9 @@ g_type_create_instance (GType type)
   instance->g_class = class;
   if (node->data->instance.instance_init)
     node->data->instance.instance_init (instance, class);
-  
+
+  TRACE(GOBJECT_OBJECT_NEW(instance, type));
+
   return instance;
 }
 
@@ -2065,12 +2102,17 @@ type_class_init_Wm (TypeNode   *node,
   TypeNode *bnode, *pnode;
   guint i;
   
+  /* Accessing data->class will work for instantiable types
+   * too because ClassData is a subset of InstanceData
+   */
   g_assert (node->is_classed && node->data &&
            node->data->class.class_size &&
            !node->data->class.class &&
            node->data->class.init_state == UNINITIALIZED);
-
-  class = g_malloc0 (node->data->class.class_size);
+  if (node->data->class.class_private_size)
+    class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size);
+  else
+    class = g_malloc0 (node->data->class.class_size);
   node->data->class.class = class;
   g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT);
   
@@ -2079,6 +2121,7 @@ type_class_init_Wm (TypeNode   *node,
       TypeNode *pnode = lookup_type_node_I (pclass->g_type);
       
       memcpy (class, pclass, pnode->data->class.class_size);
+      memcpy (G_STRUCT_MEMBER_P (class, ALIGN_STRUCT (node->data->class.class_size)), G_STRUCT_MEMBER_P (pclass, ALIGN_STRUCT (pnode->data->class.class_size)), pnode->data->class.class_private_size);
 
       if (node->is_instantiatable)
        {
@@ -2388,7 +2431,7 @@ type_data_unref_U (TypeNode *node,
 }
 
 /**
- * g_type_add_class_cache_func:
+ * g_type_add_class_cache_func: (skip)
  * @cache_data: data to be passed to @cache_func
  * @cache_func: a #GTypeClassCacheFunc
  *
@@ -2417,7 +2460,7 @@ g_type_add_class_cache_func (gpointer            cache_data,
 }
 
 /**
- * g_type_remove_class_cache_func:
+ * g_type_remove_class_cache_func: (skip)
  * @cache_data: data that was given when adding @cache_func
  * @cache_func: a #GTypeClassCacheFunc
  *
@@ -2456,7 +2499,7 @@ g_type_remove_class_cache_func (gpointer            cache_data,
 
 
 /**
- * g_type_add_interface_check:
+ * g_type_add_interface_check: (skip)
  * @check_data: data to pass to @check_func
  * @check_func: function to be called after each interface
  *              is initialized.
@@ -2490,7 +2533,7 @@ g_type_add_interface_check (gpointer                  check_data,
 }
 
 /**
- * g_type_remove_interface_check:
+ * g_type_remove_interface_check: (skip)
  * @check_data: callback data passed to g_type_add_interface_check()
  * @check_func: callback function passed to g_type_add_interface_check()
  *
@@ -2555,7 +2598,7 @@ g_type_register_fundamental (GType                       type_id,
 {
   TypeNode *node;
   
-  g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, 0);
+  g_return_val_if_type_system_uninitialized (0);
   g_return_val_if_fail (type_id > 0, 0);
   g_return_val_if_fail (type_name != NULL, 0);
   g_return_val_if_fail (info != NULL, 0);
@@ -2599,7 +2642,7 @@ g_type_register_fundamental (GType                       type_id,
 }
 
 /**
- * g_type_register_static_simple:
+ * g_type_register_static_simple: (skip)
  * @parent_type: Type from which this type will be derived.
  * @type_name: 0-terminated string used as the name of the new type.
  * @class_size: Size of the class structure (see #GTypeInfo)
@@ -2666,7 +2709,7 @@ g_type_register_static (GType            parent_type,
   TypeNode *pnode, *node;
   GType type = 0;
   
-  g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, 0);
+  g_return_val_if_type_system_uninitialized (0);
   g_return_val_if_fail (parent_type > 0, 0);
   g_return_val_if_fail (type_name != NULL, 0);
   g_return_val_if_fail (info != NULL, 0);
@@ -2721,7 +2764,7 @@ g_type_register_dynamic (GType        parent_type,
   TypeNode *pnode, *node;
   GType type;
   
-  g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, 0);
+  g_return_val_if_type_system_uninitialized (0);
   g_return_val_if_fail (parent_type > 0, 0);
   g_return_val_if_fail (type_name != NULL, 0);
   g_return_val_if_fail (plugin != NULL, 0);
@@ -2824,7 +2867,8 @@ g_type_add_interface_dynamic (GType        instance_type,
  * @type. This function will demand-create the class if it doesn't
  * exist already.
  *
- * Returns: The #GTypeClass structure for the given type ID.
+ * Returns: (type GObject.TypeClass) (transfer none): The #GTypeClass
+ *  structure for the given type ID.
  */
 gpointer
 g_type_class_ref (GType type)
@@ -2883,7 +2927,8 @@ g_type_class_ref (GType type)
 
 /**
  * g_type_class_unref:
- * @g_class: The #GTypeClass structure to unreference.
+ * @g_class: (type GObject.TypeClass): The #GTypeClass structure to
+ *  unreference.
  *
  * Decrements the reference count of the class structure being passed in.
  * Once the last reference count of a class has been released, classes
@@ -2907,8 +2952,9 @@ g_type_class_unref (gpointer g_class)
 }
 
 /**
- * g_type_class_unref_uncached:
- * @g_class: The #GTypeClass structure to unreference.
+ * g_type_class_unref_uncached: (skip)
+ * @g_class: (type GObject.TypeClass): The #GTypeClass structure to
+ *  unreference.
  *
  * A variant of g_type_class_unref() for use in #GTypeClassCacheFunc
  * implementations. It unreferences a class without consulting the chain
@@ -2940,8 +2986,9 @@ g_type_class_unref_uncached (gpointer g_class)
  * may return %NULL if the class of the type passed in does not currently
  * exist (hasn't been referenced before).
  *
- * Returns: The #GTypeClass structure for the given type ID or %NULL
- *  if the class does not currently exist.
+ * Returns: (type GObject.TypeClass) (transfer none): The #GTypeClass
+ *  structure for the given type ID or %NULL if the class does not
+ *  currently exist.
  */
 gpointer
 g_type_class_peek (GType type)
@@ -2950,14 +2997,12 @@ g_type_class_peek (GType type)
   gpointer class;
   
   node = lookup_type_node_I (type);
-  G_READ_LOCK (&type_rw_lock);
-  if (node && node->is_classed && node->data &&
+  if (node && node->is_classed && NODE_REFCOUNT (node) &&
       g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
     /* ref_count _may_ be 0 */
     class = node->data->class.class;
   else
     class = NULL;
-  G_READ_UNLOCK (&type_rw_lock);
   
   return class;
 }
@@ -2970,8 +3015,9 @@ g_type_class_peek (GType type)
  * static types.
  * 
  * Since: 2.4
- * Returns: The #GTypeClass structure for the given type ID or %NULL
- *  if the class does not currently exist or is dynamically loaded.
+ * Returns: (type GObject.TypeClass) (transfer none): The #GTypeClass
+ *  structure for the given type ID or %NULL if the class does not
+ *  currently exist or is dynamically loaded.
  */
 gpointer
 g_type_class_peek_static (GType type)
@@ -2980,22 +3026,21 @@ g_type_class_peek_static (GType type)
   gpointer class;
   
   node = lookup_type_node_I (type);
-  G_READ_LOCK (&type_rw_lock);
-  if (node && node->is_classed && node->data &&
+  if (node && node->is_classed && NODE_REFCOUNT (node) &&
       /* peek only static types: */ node->plugin == NULL &&
       g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
     /* ref_count _may_ be 0 */
     class = node->data->class.class;
   else
     class = NULL;
-  G_READ_UNLOCK (&type_rw_lock);
   
   return class;
 }
 
 /**
  * g_type_class_peek_parent:
- * @g_class: The #GTypeClass structure to retrieve the parent class for.
+ * @g_class: (type GObject.TypeClass): The #GTypeClass structure to
+ *  retrieve the parent class for.
  *
  * This is a convenience function often needed in class initializers.
  * It returns the class structure of the immediate parent type of the
@@ -3008,7 +3053,8 @@ g_type_class_peek_static (GType type)
  * g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class)));
  * </programlisting>
  *
- * Returns: The parent class of @g_class.
+ * Returns: (type GObject.TypeClass) (transfer none): The parent class
+ *  of @g_class.
  */
 gpointer
 g_type_class_peek_parent (gpointer g_class)
@@ -3036,14 +3082,15 @@ g_type_class_peek_parent (gpointer g_class)
 
 /**
  * g_type_interface_peek:
- * @instance_class: A #GTypeClass structure.
+ * @instance_class: (type GObject.TypeClass): A #GTypeClass structure.
  * @iface_type: An interface ID which this class conforms to.
  *
  * Returns the #GTypeInterface structure of an interface to which the
  * passed in class conforms.
  *
- * Returns: The GTypeInterface structure of iface_type if implemented
- *          by @instance_class, %NULL otherwise
+ * Returns: (type GObject.TypeInterface) (transfer none): The GTypeInterface
+ *  structure of iface_type if implemented by @instance_class, %NULL
+ *  otherwise
  */
 gpointer
 g_type_interface_peek (gpointer instance_class,
@@ -3068,16 +3115,17 @@ g_type_interface_peek (gpointer instance_class,
 
 /**
  * g_type_interface_peek_parent:
- * @g_iface: A #GTypeInterface structure.
+ * @g_iface: (type GObject.TypeInterface): A #GTypeInterface structure.
  *
  * Returns the corresponding #GTypeInterface structure of the parent type
  * of the instance type to which @g_iface belongs. This is useful when
  * deriving the implementation of an interface from the parent type and
  * then possibly overriding some methods.
  *
- * Returns: The corresponding #GTypeInterface structure of the parent
- *          type of the instance type to which @g_iface belongs, or
- *          %NULL if the parent type doesn't conform to the interface.
+ * Returns: (transfer none) (type GObject.TypeInterface): The
+ *  corresponding #GTypeInterface structure of the parent type of the
+ *  instance type to which @g_iface belongs, or %NULL if the parent
+ *  type doesn't conform to the interface.
  */
 gpointer
 g_type_interface_peek_parent (gpointer g_iface)
@@ -3119,9 +3167,9 @@ g_type_interface_peek_parent (gpointer g_iface)
  *
  * Since: 2.4
  *
- * Returns: the default vtable for the interface; call
- *          g_type_default_interface_unref() when you are done using
- *          the interface.
+ * Returns: (type GObject.TypeInterface) (transfer none): the default
+ *  vtable for the interface; call g_type_default_interface_unref()
+ *  when you are done using the interface.
  */
 gpointer
 g_type_default_interface_ref (GType g_type)
@@ -3169,8 +3217,9 @@ g_type_default_interface_ref (GType g_type)
  *
  * Since: 2.4
  *
- * Returns: the default vtable for the interface, or %NULL
- *          if the type is not currently in use.
+ * Returns: (type GObject.TypeInterface) (transfer none): the default
+ *  vtable for the interface, or %NULL if the type is not currently in
+ *  use.
  */
 gpointer
 g_type_default_interface_peek (GType g_type)
@@ -3179,20 +3228,19 @@ g_type_default_interface_peek (GType g_type)
   gpointer vtable;
   
   node = lookup_type_node_I (g_type);
-  G_READ_LOCK (&type_rw_lock);
-  if (node && NODE_IS_IFACE (node) && node->data && node->data->iface.dflt_vtable)
+  if (node && NODE_IS_IFACE (node) && NODE_REFCOUNT (node))
     vtable = node->data->iface.dflt_vtable;
   else
     vtable = NULL;
-  G_READ_UNLOCK (&type_rw_lock);
   
   return vtable;
 }
 
 /**
  * g_type_default_interface_unref:
- * @g_iface: the default vtable structure for a interface, as
- *           returned by g_type_default_interface_ref()
+ * @g_iface: (type GObject.TypeInterface): the default vtable
+ *  structure for a interface, as returned by
+ *  g_type_default_interface_ref()
  *
  * Decrements the reference count for the type corresponding to the
  * interface default vtable @g_iface. If the type is dynamic, then
@@ -3236,7 +3284,7 @@ g_type_name (GType type)
 {
   TypeNode *node;
   
-  g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, NULL);
+  g_return_val_if_type_system_uninitialized (NULL);
   
   node = lookup_type_node_I (type);
   
@@ -3455,12 +3503,14 @@ g_type_is_a (GType type,
 /**
  * g_type_children:
  * @type: The parent type.
- * @n_children: Optional #guint pointer to contain the number of child types.
+ * @n_children: (out) (allow-none): Optional #guint pointer to contain
+ *              the number of child types.
  *
  * Return a newly allocated and 0-terminated array of type IDs, listing the
  * child types of @type. The return value has to be g_free()ed after use.
  *
- * Returns: Newly allocated and 0-terminated array of child types.
+ * Returns: (array length=n_children) (transfer full): Newly allocated
+ *          and 0-terminated array of child types.
  */
 GType*
 g_type_children (GType  type,
@@ -3496,14 +3546,15 @@ g_type_children (GType  type,
 /**
  * g_type_interfaces:
  * @type: The type to list interface types for.
- * @n_interfaces: Optional #guint pointer to contain the number of
- *                interface types.
+ * @n_interfaces: (out) (allow-none): Optional #guint pointer to
+ *                contain the number of interface types.
  *
  * Return a newly allocated and 0-terminated array of type IDs, listing the
  * interface types that @type conforms to. The return value has to be
  * g_free()ed after use.
  *
- * Returns: Newly allocated and 0-terminated array of interface types.
+ * Returns: (array length=n_interfaces) (transfer full): Newly
+ *          allocated and 0-terminated array of interface types.
  */
 GType*
 g_type_interfaces (GType  type,
@@ -3601,7 +3652,7 @@ type_get_qdata_L (TypeNode *node,
  * Obtains data which has previously been attached to @type
  * with g_type_set_qdata().
  *
- * Returns: the data, or %NULL if no data was found
+ * Returns: (transfer none): the data, or %NULL if no data was found
  */
 gpointer
 g_type_get_qdata (GType  type,
@@ -3707,8 +3758,8 @@ type_add_flags_W (TypeNode  *node,
 /**
  * g_type_query:
  * @type: the #GType value of a static, classed type.
- * @query: A user provided structure that is filled in with constant values
- *  upon success.
+ * @query: (out caller-allocates): A user provided structure that is
+ *         filled in with constant values upon success.
  *
  * Queries the type system for information about a specific type.
  * This function will fill in a user-provided structure to hold
@@ -3789,8 +3840,8 @@ g_type_test_flags (GType type,
  * Returns the #GTypePlugin structure for @type or
  * %NULL if @type does not have a #GTypePlugin structure.
  *
- * Returns: The corresponding plugin if @type is a dynamic type,
- *  %NULL otherwise.
+ * Returns: (transfer none): The corresponding plugin if @type is a
+ *          dynamic type, %NULL otherwise.
  */
 GTypePlugin*
 g_type_get_plugin (GType type)
@@ -3812,8 +3863,8 @@ g_type_get_plugin (GType type)
  * @interface_type has not been added to @instance_type or does not
  * have a #GTypePlugin structure. See g_type_add_interface_dynamic().
  *
- * Returns: the #GTypePlugin for the dynamic interface @interface_type
- *  of @instance_type.
+ * Returns: (transfer none): the #GTypePlugin for the dynamic
+ *          interface @interface_type of @instance_type.
  */
 GTypePlugin*
 g_type_interface_get_plugin (GType instance_type,
@@ -4088,7 +4139,7 @@ g_type_check_value_holds (GValue *value,
 }
 
 /**
- * g_type_value_table_peek:
+ * g_type_value_table_peek: (skip)
  * @type: A #GType value.
  *
  * Returns the location of the #GTypeValueTable associated with @type.
@@ -4105,14 +4156,9 @@ g_type_value_table_peek (GType type)
   GTypeValueTable *vtable = NULL;
   TypeNode *node = lookup_type_node_I (type);
   gboolean has_refed_data, has_table;
-  TypeData *data;
 
-  /* speed up common code path, we're not 100% safe here,
-   * but we should only get called with referenced types anyway
-   */
-  data = node ? node->data : NULL;
-  if (node && node->mutatable_check_cache)
-    return data->common.value_table;
+  if (node && NODE_REFCOUNT (node) && node->mutatable_check_cache)
+    return node->data->common.value_table;
 
   G_READ_LOCK (&type_rw_lock);
   
@@ -4175,6 +4221,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:
@@ -4191,7 +4265,12 @@ g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
   GTypeInfo info;
   TypeNode *node;
   volatile GType votype;
-  
+
+#ifdef G_THREADS_ENABLED
+  if (!g_thread_get_initialized())
+    g_thread_init (NULL);
+#endif
+
   G_LOCK (type_init_lock);
   
   G_WRITE_LOCK (&type_rw_lock);
@@ -4295,6 +4374,8 @@ g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
  * to initialize the type system and assorted other code portions
  * (such as the various fundamental type implementations or the signal
  * system).
+ *
+ * Since version 2.24 this also initializes the thread system
  */
 void
 g_type_init (void)
@@ -4307,38 +4388,58 @@ g_type_init (void)
  * @g_class: class structure for an instantiatable type
  * @private_size: size of private structure.
  *
- * Registers a private structure for an instantiatable type;
- * when an object is allocated, the private structures for
+ * Registers a private structure for an instantiatable type.
+ *
+ * When an object is allocated, the private structures for
  * the type and all of its parent types are allocated
  * sequentially in the same memory block as the public
- * structures. This function should be called in the
- * type's class_init() function. The private structure can
- * be retrieved using the G_TYPE_INSTANCE_GET_PRIVATE() macro.
+ * structures.
+ *
+ * Note that the accumulated size of the private structures of
+ * a type and all its parent types cannot excced 64kB.
+ *
+ * This function should be called in the type's class_init() function.
+ * The private structure can be retrieved using the
+ * G_TYPE_INSTANCE_GET_PRIVATE() macro.
+ *
  * The following example shows attaching a private structure
  * <structname>MyObjectPrivate</structname> to an object
  * <structname>MyObject</structname> defined in the standard GObject
  * fashion.
+ * type's class_init() function.
  *
  * |[
+ * typedef struct _MyObject        MyObject;
  * typedef struct _MyObjectPrivate MyObjectPrivate;
  *
+ * struct _MyObject {
+ *  GObject parent;
+ *
+ *  MyObjectPrivate *priv;
+ * };
+ *
  * struct _MyObjectPrivate {
  *   int some_field;
  * };
  *
- * #define MY_OBJECT_GET_PRIVATE(o)  \
- *    (G_TYPE_INSTANCE_GET_PRIVATE ((o), MY_TYPE_OBJECT, MyObjectPrivate))
- *
  * static void
  * my_object_class_init (MyObjectClass *klass)
  * {
  *   g_type_class_add_private (klass, sizeof (MyObjectPrivate));
  * }
  *
+ * static void
+ * my_object_init (MyObject *my_object)
+ * {
+ *   my_object->priv = G_TYPE_INSTANCE_GET_PRIVATE (my_object,
+ *                                                  MY_TYPE_OBJECT,
+ *                                                  MyObjectPrivate);
+ * }
+ *
  * static int
  * my_object_get_some_field (MyObject *my_object)
  * {
- *   MyObjectPrivate *priv = MY_OBJECT_GET_PRIVATE (my_object);
+ *   MyObjectPrivate *priv = my_object->priv;
  *
  *   return priv->some_field;
  * }
@@ -4355,6 +4456,7 @@ g_type_class_add_private (gpointer g_class,
   gsize offset;
 
   g_return_if_fail (private_size > 0);
+  g_return_if_fail (private_size <= 0xffff);
 
   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != g_class)
     {
@@ -4376,6 +4478,9 @@ g_type_class_add_private (gpointer g_class,
   G_WRITE_LOCK (&type_rw_lock);
 
   offset = ALIGN_STRUCT (node->data->instance.private_size);
+
+  g_assert (offset + private_size <= 0xffff);
+
   node->data->instance.private_size = offset + private_size;
   
   G_WRITE_UNLOCK (&type_rw_lock);
@@ -4442,5 +4547,98 @@ g_type_instance_get_private (GTypeInstance *instance,
   return G_STRUCT_MEMBER_P (instance, offset);
 }
 
-#define __G_TYPE_C__
-#include "gobjectaliasdef.c"
+/**
+ * g_type_add_class_private:
+ * @class_type: GType of an classed type.
+ * @private_size: size of private structure.
+ *
+ * Registers a private class structure for a classed type;
+ * when the class is allocated, the private structures for
+ * the class and all of its parent types are allocated
+ * sequentially in the same memory block as the public
+ * structures. This function should be called in the
+ * type's get_type() function after the type is registered.
+ * The private structure can be retrieved using the
+ * G_TYPE_CLASS_GET_PRIVATE() macro.
+ *
+ * Since: 2.24
+ */
+void
+g_type_add_class_private (GType    class_type,
+                         gsize    private_size)
+{
+  TypeNode *node = lookup_type_node_I (class_type);
+  gsize offset;
+
+  g_return_if_fail (private_size > 0);
+
+  if (!node || !node->is_classed || !node->data)
+    {
+      g_warning ("cannot add class private field to invalid type '%s'",
+                type_descriptive_name_I (class_type));
+      return;
+    }
+
+  if (NODE_PARENT_TYPE (node))
+    {
+      TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
+      if (node->data->class.class_private_size != pnode->data->class.class_private_size)
+       {
+         g_warning ("g_type_add_class_private() called multiple times for the same type");
+         return;
+       }
+    }
+  
+  G_WRITE_LOCK (&type_rw_lock);
+
+  offset = ALIGN_STRUCT (node->data->class.class_private_size);
+  node->data->class.class_private_size = offset + private_size;
+
+  G_WRITE_UNLOCK (&type_rw_lock);
+}
+
+gpointer
+g_type_class_get_private (GTypeClass *klass,
+                         GType       private_type)
+{
+  TypeNode *class_node;
+  TypeNode *private_node;
+  TypeNode *parent_node;
+  gsize offset;
+
+  g_return_val_if_fail (klass != NULL, NULL);
+
+  class_node = lookup_type_node_I (klass->g_type);
+  if (G_UNLIKELY (!class_node || !class_node->is_classed))
+    {
+      g_warning ("class of invalid type `%s'",
+                type_descriptive_name_I (klass->g_type));
+      return NULL;
+    }
+
+  private_node = lookup_type_node_I (private_type);
+  if (G_UNLIKELY (!private_node || !NODE_IS_ANCESTOR (private_node, class_node)))
+    {
+      g_warning ("attempt to retrieve private data for invalid type '%s'",
+                type_descriptive_name_I (private_type));
+      return NULL;
+    }
+
+  offset = ALIGN_STRUCT (class_node->data->class.class_size);
+
+  if (NODE_PARENT_TYPE (private_node))
+    {
+      parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
+      g_assert (parent_node->data && NODE_REFCOUNT (parent_node) > 0);
+
+      if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size))
+       {
+         g_warning ("g_type_instance_get_class_private() requires a prior call to g_type_class_add_class_private()");
+         return NULL;
+       }
+
+      offset += ALIGN_STRUCT (parent_node->data->class.class_private_size);
+    }
+
+  return G_STRUCT_MEMBER_P (klass, offset);
+}