Less locking in gtype.c



Here is a patch that removes a lot of the locking in gtype.c. In a (very) 
unscientific test it sped up G_TYPE_CHECK_INSTANCE_TYPE by about 150%.

What it does is essentially that it removes the static_type_nodes[] 
bottleneck, replacing it with a system where you can lookup a type node 
from a GType without locking.

The actual implementation is slightly evil:
GType is now a gsize, meaning we can stick a pointer there when we need.

The lowest bit of GType is reserved for G_SIGNAL_TYPE_STATIC_SCOPE, as 
evidenced by G_TYPE_FLAG_RESERVED_ID_BIT now being 1. So all odd GTypes 
are invalid.

For GTypes less than 1024 we index (type>>1) into a static 512 
element array of TypeNode pointers to get the typenode. GTypes 0-510 are 
considered fundamental types, and GTypes 512-1020 are "Constant types", 
i.e. non-fundamental types that have a GType value that is constant. This 
corresponds to the built in glib types that we use in switch cases etc.

For GTypes larger than 1024, the value is actually a pointer to the 
TypeNode. This means that type node lookups are extremely fast, and don't 
need locking.

This leads to lots of removed locks in gtype.c, as many calls locked just 
so they could call lookup_type_node_L(). 

In fact, with some rearranging of type_node_is_a_L i got it to only lock 
when needed (i.e. when the interface type is a real interface). This is 
what sped up G_TYPE_CHECK_INSTANCE_TYPE by 150%.

Anyway, here is the patch. I've only done one sweep through gtype.c (at 2 
in the night), so i'm sure there are some issues with the threadsafeness. 
I'd appreciate if more people looked at it.

/ Alex

Index: gobject/gboxed.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gboxed.c,v
retrieving revision 1.10
diff -u -p -r1.10 gboxed.c
--- gobject/gboxed.c	2001/06/19 12:13:22	1.10
+++ gobject/gboxed.c	2001/09/05 15:13:42
@@ -41,6 +41,12 @@ typedef struct
 static gint	boxed_nodes_cmp		(gconstpointer	p1,
 					 gconstpointer	p2);
 
+static GType    g_boxed_type_register_static_internal (const gchar   *name,
+						       GBoxedInitFunc boxed_init,
+						       GBoxedCopyFunc boxed_copy,
+						       GBoxedFreeFunc boxed_free,
+						       gboolean	     is_refcounted,
+						       GType         opt_type);
 
 /* --- variables --- */
 static GBSearchArray boxed_bsa = G_STATIC_BSEARCH_ARRAY_INIT (sizeof (BoxedNode), boxed_nodes_cmp, 0);
@@ -142,39 +148,43 @@ g_boxed_type_init (void)  /* sync with g
 
   /* boxed: G_TYPE_CLOSURE
    */
-  type = g_boxed_type_register_static ("GClosure",
-				       (GBoxedInitFunc) NULL,
-				       (GBoxedCopyFunc) g_closure_ref,
-				       (GBoxedFreeFunc) g_closure_unref,
-				       TRUE);
+  type = g_boxed_type_register_static_internal ("GClosure",
+						(GBoxedInitFunc) NULL,
+						(GBoxedCopyFunc) g_closure_ref,
+						(GBoxedFreeFunc) g_closure_unref,
+						TRUE,
+						G_TYPE_CLOSURE);
   g_assert (type == G_TYPE_CLOSURE);
 
   /* boxed: G_TYPE_VALUE
    */
-  type = g_boxed_type_register_static ("GValue",
-				       (GBoxedInitFunc) NULL,
-				       value_copy,
-				       value_free,
-				       FALSE);
+  type = g_boxed_type_register_static_internal ("GValue",
+						(GBoxedInitFunc) NULL,
+						value_copy,
+						value_free,
+						FALSE,
+						G_TYPE_VALUE);
   g_assert (type == G_TYPE_VALUE);
 
   /* boxed: G_TYPE_VALUE_ARRAY
    */
-  type = g_boxed_type_register_static ("GValueArray",
-				       value_array_init,	/* don't allow NULL values */
-				       (GBoxedCopyFunc) g_value_array_copy,
-				       (GBoxedFreeFunc) g_value_array_free,
-				       FALSE);
+  type = g_boxed_type_register_static_internal ("GValueArray",
+						value_array_init,	/* don't allow NULL values */
+						(GBoxedCopyFunc) g_value_array_copy,
+						(GBoxedFreeFunc) g_value_array_free,
+						FALSE,
+						G_TYPE_VALUE_ARRAY);
   g_assert (type == G_TYPE_VALUE_ARRAY);
 
   /* boxed: G_TYPE_GSTRING
    * yes, the naming is a bit odd, but GString is obviously not G_TYPE_STRING
    */
-  type = g_boxed_type_register_static ("GString",
-				       gstring_init,		/* don't allow NULL values */
-				       gstring_copy,
-				       gstring_free,
-				       FALSE);
+  type = g_boxed_type_register_static_internal ("GString",
+						gstring_init,		/* don't allow NULL values */
+						gstring_copy,
+						gstring_free,
+						FALSE,
+						G_TYPE_GSTRING);
   g_assert (type == G_TYPE_GSTRING);
 }
 
@@ -279,12 +289,13 @@ boxed_proxy_lcopy_value (const GValue *v
   return NULL;
 }
 
-GType
-g_boxed_type_register_static (const gchar   *name,
-			      GBoxedInitFunc boxed_init,
-			      GBoxedCopyFunc boxed_copy,
-			      GBoxedFreeFunc boxed_free,
-			      gboolean	     is_refcounted)
+static GType
+g_boxed_type_register_static_internal (const gchar   *name,
+				       GBoxedInitFunc boxed_init,
+				       GBoxedCopyFunc boxed_copy,
+				       GBoxedFreeFunc boxed_free,
+				       gboolean	     is_refcounted,
+				       GType         opt_type)
 {
   static const GTypeValueTable vtable = {
     boxed_proxy_value_init,
@@ -315,7 +326,7 @@ g_boxed_type_register_static (const gcha
   g_return_val_if_fail (boxed_free != NULL, 0);
   g_return_val_if_fail (g_type_from_name (name) == 0, 0);
 
-  type = g_type_register_static (G_TYPE_BOXED, name, &type_info, 0);
+  type = g_type_register_static_constant (G_TYPE_BOXED, name, &type_info, 0, opt_type);
 
   /* install proxy functions upon successfull registration */
   if (type)
@@ -331,6 +342,22 @@ g_boxed_type_register_static (const gcha
     }
 
   return type;
+}
+
+GType
+g_boxed_type_register_static (const gchar   *name,
+			       GBoxedInitFunc boxed_init,
+			       GBoxedCopyFunc boxed_copy,
+			       GBoxedFreeFunc boxed_free,
+			       gboolean	     is_refcounted)
+{
+  return g_boxed_type_register_static_internal (name,
+						boxed_init,
+						boxed_copy,
+						boxed_free,
+						is_refcounted,
+						0);
+  
 }
 
 gpointer
Index: gobject/gparam.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gparam.c,v
retrieving revision 1.16
diff -u -p -r1.16 gparam.c
--- gobject/gparam.c	2001/06/28 17:05:12	1.16
+++ gobject/gparam.c	2001/09/05 15:13:43
@@ -885,8 +885,9 @@ default_values_cmp (GParamSpec   *pspec,
 }
 
 GType
-g_param_type_register_static (const gchar              *name,
-			      const GParamSpecTypeInfo *pspec_info)
+g_param_type_register_static_constant (const gchar              *name,
+				       const GParamSpecTypeInfo *pspec_info,
+				       GType                     opt_type)
 {
   GTypeInfo info = {
     sizeof (GParamSpecClass),      /* class_size */
@@ -921,9 +922,17 @@ g_param_type_register_static (const gcha
   cinfo->values_cmp = pspec_info->values_cmp ? pspec_info->values_cmp : default_values_cmp;
   info.class_data = cinfo;
 
-  return g_type_register_static (G_TYPE_PARAM, name, &info, 0);
+  return g_type_register_static_constant (G_TYPE_PARAM, name, &info, 0, opt_type);
 }
 
+GType
+g_param_type_register_static (const gchar              *name,
+			      const GParamSpecTypeInfo *pspec_info)
+{
+  return g_param_type_register_static_constant (name,
+						pspec_info,
+						0);
+}
 void
 g_value_set_param (GValue     *value,
 		   GParamSpec *param)
Index: gobject/gparam.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gparam.h,v
retrieving revision 1.14
diff -u -p -r1.14 gparam.h
--- gobject/gparam.h	2001/06/28 17:05:12	1.14
+++ gobject/gparam.h	2001/09/05 15:13:43
@@ -178,6 +178,9 @@ GParamSpec**	g_param_spec_pool_list		(GP
 						 GType		 owner_type,
 						 guint		*n_pspecs_p);
 
+GType           g_param_type_register_static_constant (const gchar              *name,
+						       const GParamSpecTypeInfo *pspec_info,
+						       GType                     opt_type);
 
 
 /* contracts:
Index: gobject/gparamspecs.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gparamspecs.c,v
retrieving revision 1.16
diff -u -p -r1.16 gparamspecs.c
--- gobject/gparamspecs.c	2001/05/10 13:58:40	1.16
+++ gobject/gparamspecs.c	2001/09/05 15:13:43
@@ -936,7 +936,7 @@ g_param_spec_types_init (void)	/* sync w
       param_char_validate,	/* value_validate */
       param_int_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamChar", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamChar", &pspec_info, G_TYPE_PARAM_CHAR);
     g_assert (type == G_TYPE_PARAM_CHAR);
   }
   
@@ -953,7 +953,7 @@ g_param_spec_types_init (void)	/* sync w
       param_uchar_validate,	/* value_validate */
       param_uint_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamUChar", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamUChar", &pspec_info, G_TYPE_PARAM_UCHAR);
     g_assert (type == G_TYPE_PARAM_UCHAR);
   }
   
@@ -970,7 +970,7 @@ g_param_spec_types_init (void)	/* sync w
       param_boolean_validate,     /* value_validate */
       param_int_values_cmp,       /* values_cmp */
     };
-    type = g_param_type_register_static ("GParamBoolean", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamBoolean", &pspec_info, G_TYPE_PARAM_BOOLEAN);
     g_assert (type == G_TYPE_PARAM_BOOLEAN);
   }
   
@@ -987,7 +987,7 @@ g_param_spec_types_init (void)	/* sync w
       param_int_validate,	/* value_validate */
       param_int_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamInt", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamInt", &pspec_info, G_TYPE_PARAM_INT);
     g_assert (type == G_TYPE_PARAM_INT);
   }
   
@@ -1004,7 +1004,7 @@ g_param_spec_types_init (void)	/* sync w
       param_uint_validate,	/* value_validate */
       param_uint_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamUInt", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamUInt", &pspec_info, G_TYPE_PARAM_UINT);
     g_assert (type == G_TYPE_PARAM_UINT);
   }
   
@@ -1021,7 +1021,7 @@ g_param_spec_types_init (void)	/* sync w
       param_long_validate,	/* value_validate */
       param_long_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamLong", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamLong", &pspec_info, G_TYPE_PARAM_LONG);
     g_assert (type == G_TYPE_PARAM_LONG);
   }
   
@@ -1038,7 +1038,7 @@ g_param_spec_types_init (void)	/* sync w
       param_ulong_validate,	/* value_validate */
       param_ulong_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamULong", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamULong", &pspec_info, G_TYPE_PARAM_ULONG);
     g_assert (type == G_TYPE_PARAM_ULONG);
   }
 
@@ -1055,7 +1055,7 @@ g_param_spec_types_init (void)	/* sync w
       param_unichar_validate,	 /* value_validate */
       param_unichar_values_cmp,	 /* values_cmp */
     };
-    type = g_param_type_register_static ("GParamUnichar", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamUnichar", &pspec_info, G_TYPE_PARAM_UNICHAR);
     g_assert (type == G_TYPE_PARAM_UNICHAR);
   }
 
@@ -1072,7 +1072,7 @@ g_param_spec_types_init (void)	/* sync w
       param_enum_validate,	/* value_validate */
       param_long_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamEnum", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamEnum", &pspec_info, G_TYPE_PARAM_ENUM);
     g_assert (type == G_TYPE_PARAM_ENUM);
   }
   
@@ -1089,7 +1089,7 @@ g_param_spec_types_init (void)	/* sync w
       param_flags_validate,	/* value_validate */
       param_ulong_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamFlags", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamFlags", &pspec_info, G_TYPE_PARAM_FLAGS);
     g_assert (type == G_TYPE_PARAM_FLAGS);
   }
   
@@ -1106,7 +1106,7 @@ g_param_spec_types_init (void)	/* sync w
       param_float_validate,	/* value_validate */
       param_float_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamFloat", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamFloat", &pspec_info, G_TYPE_PARAM_FLOAT);
     g_assert (type == G_TYPE_PARAM_FLOAT);
   }
   
@@ -1123,7 +1123,7 @@ g_param_spec_types_init (void)	/* sync w
       param_double_validate,		/* value_validate */
       param_double_values_cmp,		/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamDouble", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamDouble", &pspec_info, G_TYPE_PARAM_DOUBLE);
     g_assert (type == G_TYPE_PARAM_DOUBLE);
   }
   
@@ -1140,7 +1140,7 @@ g_param_spec_types_init (void)	/* sync w
       param_string_validate,		/* value_validate */
       param_string_values_cmp,		/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamString", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamString", &pspec_info, G_TYPE_PARAM_STRING);
     g_assert (type == G_TYPE_PARAM_STRING);
   }
   
@@ -1157,7 +1157,7 @@ g_param_spec_types_init (void)	/* sync w
       param_param_validate,	/* value_validate */
       param_pointer_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamParam", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamParam", &pspec_info, G_TYPE_PARAM_PARAM);
     g_assert (type == G_TYPE_PARAM_PARAM);
   }
   
@@ -1174,7 +1174,7 @@ g_param_spec_types_init (void)	/* sync w
       param_boxed_validate,	/* value_validate */
       param_boxed_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamBoxed", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamBoxed", &pspec_info, G_TYPE_PARAM_BOXED);
     g_assert (type == G_TYPE_PARAM_BOXED);
   }
 
@@ -1191,7 +1191,7 @@ g_param_spec_types_init (void)	/* sync w
       param_pointer_validate,	   /* value_validate */
       param_pointer_values_cmp,	   /* values_cmp */
     };
-    type = g_param_type_register_static ("GParamPointer", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamPointer", &pspec_info, G_TYPE_PARAM_POINTER);
     g_assert (type == G_TYPE_PARAM_POINTER);
   }
   
@@ -1208,7 +1208,7 @@ g_param_spec_types_init (void)	/* sync w
       param_value_array_validate,	/* value_validate */
       param_value_array_values_cmp,	/* values_cmp */
     };
-    type = g_param_type_register_static ("GParamValueArray", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamValueArray", &pspec_info, G_TYPE_PARAM_VALUE_ARRAY);
     g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
   }
 
@@ -1225,7 +1225,7 @@ g_param_spec_types_init (void)	/* sync w
       param_closure_validate,	    /* value_validate */
       param_closure_values_cmp,     /* values_cmp */
     };
-    type = g_param_type_register_static ("GParamClosure", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamClosure", &pspec_info, G_TYPE_PARAM_CLOSURE);
     g_assert (type == G_TYPE_PARAM_CLOSURE);
   }
   
@@ -1242,7 +1242,7 @@ g_param_spec_types_init (void)	/* sync w
       param_object_validate,	 /* value_validate */
       param_object_values_cmp,	 /* values_cmp */
     };
-    type = g_param_type_register_static ("GParamObject", &pspec_info);
+    type = g_param_type_register_static_constant ("GParamObject", &pspec_info, G_TYPE_PARAM_OBJECT);
     g_assert (type == G_TYPE_PARAM_OBJECT);
   }
 }
Index: gobject/gtype.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gtype.c,v
retrieving revision 1.32
diff -u -p -r1.32 gtype.c
--- gobject/gtype.c	2001/08/15 09:19:52	1.32
+++ gobject/gtype.c	2001/09/05 15:13:44
@@ -116,7 +116,7 @@ typedef struct _IFaceHolder	IFaceHolder;
 
 
 /* --- prototypes --- */
-static inline GTypeFundamentalInfo*	type_node_fundamental_info_L	(TypeNode		*node);
+static inline GTypeFundamentalInfo*	type_node_fundamental_info_I	(TypeNode		*node);
 static	      void			type_add_flags_W		(TypeNode		*node,
 									 GTypeFlags		 flags);
 static	      void			type_data_make_W		(TypeNode		*node,
@@ -142,6 +142,7 @@ struct _GValue	/* kludge, keep in sync w
 struct _TypeNode
 {
   GTypePlugin *plugin;
+  GType        fundamental_type;
   guint        n_children : 12;
   guint        n_supers : 8;
   guint        _prot_n_ifaces_prerequisites : 9;
@@ -224,7 +225,7 @@ struct _InstanceData
   guint16            instance_size;
   guint16            n_preallocs;
   GInstanceInitFunc  instance_init;
-  GMemChunk        *mem_chunk;
+  GMemChunk         *mem_chunk;
 };
 union _TypeData
 {
@@ -254,41 +255,48 @@ const char  *g_log_domain_gruntime = "GR
 
 
 /* --- type nodes --- */
-static GHashTable       *static_type_nodes_ht = NULL;
-static GType            *static_branch_seqnos = NULL;
-static TypeNode       ***static_type_nodes = NULL;
+static GHashTable     *static_type_nodes_ht = NULL;
+/* Fundamental (even 0-510) and constant (even 512-1022) type nodes */
+static TypeNode       *static_low_type_nodes[512] = {NULL};
 
+
 static inline TypeNode*
-lookup_type_node_L (register GType utype)
+lookup_type_node_I (GType utype)
 {
-  register GType ftype = G_TYPE_FUNDAMENTAL (utype);
-  register GType b_seqno = G_TYPE_BRANCH_SEQNO (utype);
-  
-  if (ftype < static_last_fundamental_id && b_seqno < static_branch_seqnos[ftype])
-    return static_type_nodes[ftype][b_seqno];
+  if (utype < 1024)
+    return static_low_type_nodes[utype>>1];
   else
-    return NULL;
+    return (TypeNode *)utype;
 }
 
+GType
+g_type_fundamental (GType type)
+{
+  TypeNode *node = lookup_type_node_I (type);
+  return node->fundamental_type;
+}
+
 static TypeNode*
 type_node_any_new_W (TypeNode             *pnode,
 		     GType                 ftype,
 		     const gchar          *name,
 		     GTypePlugin          *plugin,
-		     GTypeFundamentalFlags type_flags)
+		     GTypeFundamentalFlags type_flags,
+		     GType                 opt_type)
 {
-  guint branch_last, n_supers;
+  guint n_supers;
   GType type;
   TypeNode *node;
   guint i, node_size = 0;
+
+  g_assert (ftype < G_TYPE_FUNDAMENTAL_MAX);
+  g_assert ((ftype & G_TYPE_FLAG_RESERVED_ID_BIT) == 0);
+
+  g_assert (opt_type == 0 || (opt_type > G_TYPE_FUNDAMENTAL_MAX && opt_type < G_TYPE_CONSTANT_MAX));
   
   n_supers = pnode ? pnode->n_supers + 1 : 0;
-  branch_last = static_branch_seqnos[ftype]++;
-  type = G_TYPE_DERIVE_ID (ftype, branch_last);
-  g_assert ((type & G_TYPE_FLAG_RESERVED_ID_BIT) == 0);
-  if (!branch_last || g_bit_storage (branch_last - 1) < g_bit_storage (static_branch_seqnos[ftype] - 1))
-    static_type_nodes[ftype] = g_renew (TypeNode*, static_type_nodes[ftype], 1 << g_bit_storage (static_branch_seqnos[ftype] - 1));
-  
+
+ 
   if (!pnode)
     node_size += SIZEOF_FUNDAMENTAL_INFO;	      /* fundamental type info */
   node_size += SIZEOF_BASE_TYPE_NODE ();	      /* TypeNode structure */
@@ -296,8 +304,27 @@ type_node_any_new_W (TypeNode           
   node = g_malloc0 (node_size);
   if (!pnode)					      /* offset fundamental types */
     node = G_STRUCT_MEMBER_P (node, SIZEOF_FUNDAMENTAL_INFO);
-  static_type_nodes[ftype][branch_last] = node;
+
+  node->fundamental_type = ftype;
+  
+  if (!pnode)
+    {
+      type = ftype;
+      static_low_type_nodes[type>>1] = node;
+    }
+  else
+    {
+      if (opt_type)
+	{
+	  type = opt_type;
+	  static_low_type_nodes[type>>1] = node;
+	}
+      else
+	type = (GType)node;
+    }
   
+  g_assert ((type & G_TYPE_FLAG_RESERVED_ID_BIT) == 0);
+  
   node->n_supers = n_supers;
   if (!pnode)
     {
@@ -358,12 +385,12 @@ type_node_any_new_W (TypeNode           
 }
 
 static inline GTypeFundamentalInfo*
-type_node_fundamental_info_L (TypeNode *node)
+type_node_fundamental_info_I (TypeNode *node)
 {
-  GType ftype = G_TYPE_FUNDAMENTAL (NODE_TYPE (node));
+  GType ftype = node->fundamental_type;
   
   if (ftype != NODE_TYPE (node))
-    node = lookup_type_node_L (ftype);
+    node = lookup_type_node_I (ftype);
   
   return node ? G_STRUCT_MEMBER_P (node, - SIZEOF_FUNDAMENTAL_INFO) : NULL;
 }
@@ -375,30 +402,20 @@ type_node_fundamental_new_W (GType      
 {
   GTypeFundamentalInfo *finfo;
   TypeNode *node;
-  guint i, flast;
+  guint flast;
   
   flast = static_last_fundamental_id;
   
-  g_assert (ftype == G_TYPE_FUNDAMENTAL (ftype));
+  g_assert (ftype < G_TYPE_FUNDAMENTAL_MAX);
+  g_assert ((ftype & G_TYPE_FLAG_RESERVED_ID_BIT) == 0);
   
   type_flags &= TYPE_FUNDAMENTAL_FLAG_MASK;
   
   static_last_fundamental_id = MAX (static_last_fundamental_id, ftype + 1);
-  if (static_last_fundamental_id > flast)
-    {
-      static_type_nodes = g_renew (TypeNode**, static_type_nodes, static_last_fundamental_id);
-      static_branch_seqnos = g_renew (GType, static_branch_seqnos, static_last_fundamental_id);
-      for (i = flast; i < static_last_fundamental_id; i++)
-	{
-	  static_type_nodes[i] = NULL;
-	  static_branch_seqnos[i] = 0;
-	}
-    }
-  g_assert (static_branch_seqnos[ftype] == 0);
   
-  node = type_node_any_new_W (NULL, ftype, name, NULL, type_flags);
+  node = type_node_any_new_W (NULL, ftype, name, NULL, type_flags, 0);
   
-  finfo = type_node_fundamental_info_L (node);
+  finfo = type_node_fundamental_info_I (node);
   finfo->type_flags = type_flags;
   
   return node;
@@ -407,14 +424,15 @@ type_node_fundamental_new_W (GType      
 static TypeNode*
 type_node_new_W (TypeNode    *pnode,
 		 const gchar *name,
-		 GTypePlugin *plugin)
+		 GTypePlugin *plugin,
+		 GType        opt_type)
      
 {
   g_assert (pnode);
   g_assert (pnode->n_supers < MAX_N_SUPERS);
   g_assert (pnode->n_children < MAX_N_CHILDREN);
   
-  return type_node_any_new_W (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (pnode)), name, plugin, 0);
+  return type_node_any_new_W (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (pnode)), name, plugin, 0, opt_type);
 }
 
 static inline IFaceEntry*
@@ -482,11 +500,11 @@ type_lookup_prerequisite_L (TypeNode *if
 }
 
 static inline gchar*
-type_descriptive_name_L (GType type)
+type_descriptive_name_I (GType type)
 {
   if (type)
     {
-      TypeNode *node = lookup_type_node_L (type);
+      TypeNode *node = lookup_type_node_I (type);
       
       return node ? NODE_NAME (node) : "<unknown>";
     }
@@ -494,19 +512,6 @@ type_descriptive_name_L (GType type)
     return "<invalid>";
 }
 
-static inline gchar*
-type_descriptive_name_U (GType type)
-{
-  const gchar *name;
-  
-  G_READ_LOCK (&type_rw_lock);
-  name = type_descriptive_name_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
-  
-  return (gchar *)name;
-}
-
-
 /* --- type consistency checks --- */
 static gboolean
 check_plugin_U (GTypePlugin *plugin,
@@ -577,27 +582,24 @@ check_type_name_U (const gchar *type_nam
 }
 
 static gboolean
-check_derivation_U (GType        parent_type,
+check_derivation_I (GType        parent_type,
 		    const gchar *type_name)
 {
   TypeNode *pnode;
   GTypeFundamentalInfo* finfo;
   
-  G_READ_LOCK (&type_rw_lock);
-  pnode = lookup_type_node_L (parent_type);
+  pnode = lookup_type_node_I (parent_type);
   if (!pnode)
     {
-      G_READ_UNLOCK (&type_rw_lock);
       g_warning ("cannot derive type `%s' from invalid parent type `%s'",
 		 type_name,
-		 type_descriptive_name_U (parent_type));
+		 type_descriptive_name_I (parent_type));
       return FALSE;
     }
-  finfo = type_node_fundamental_info_L (pnode);
+  finfo = type_node_fundamental_info_I (pnode);
   /* ensure flat derivability */
   if (!(finfo->type_flags & G_TYPE_FLAG_DERIVABLE))
     {
-      G_READ_UNLOCK (&type_rw_lock);
       g_warning ("cannot derive `%s' from non-derivable parent type `%s'",
 		 type_name,
 		 NODE_NAME (pnode));
@@ -607,13 +609,11 @@ check_derivation_U (GType        parent_
   if (parent_type != G_TYPE_FUNDAMENTAL (parent_type) &&
       !(finfo->type_flags & G_TYPE_FLAG_DEEP_DERIVABLE))
     {
-      G_READ_UNLOCK (&type_rw_lock);
       g_warning ("cannot derive `%s' from non-fundamental parent type `%s'",
 		 type_name,
 		 NODE_NAME (pnode));
       return FALSE;
     }
-  G_READ_UNLOCK (&type_rw_lock);
   
   return TRUE;
 }
@@ -695,12 +695,12 @@ check_value_table_I (const gchar        
 }
 
 static gboolean
-check_type_info_L (TypeNode        *pnode,
+check_type_info_I (TypeNode        *pnode,
 		   GType            ftype,
 		   const gchar     *type_name,
 		   const GTypeInfo *info)
 {
-  GTypeFundamentalInfo *finfo = type_node_fundamental_info_L (lookup_type_node_L (ftype));
+  GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (lookup_type_node_I (ftype));
   gboolean is_interface = G_TYPE_IS_INTERFACE (ftype);
   
   /* check instance members */
@@ -788,7 +788,7 @@ find_conforming_type_L (TypeNode *pnode,
     return pnode;
   
   for (i = 0; i < pnode->n_children && !node; i++)
-    node = find_conforming_type_L (lookup_type_node_L (pnode->children[i]), iface);
+    node = find_conforming_type_L (lookup_type_node_I (pnode->children[i]), iface);
   
   return node;
 }
@@ -797,24 +797,24 @@ static gboolean
 check_add_interface_L (GType instance_type,
 		       GType iface_type)
 {
-  TypeNode *node = lookup_type_node_L (instance_type);
-  TypeNode *iface = lookup_type_node_L (iface_type);
+  TypeNode *node = lookup_type_node_I (instance_type);
+  TypeNode *iface = lookup_type_node_I (iface_type);
   TypeNode *tnode;
   
   if (!node || !node->is_instantiatable)
     {
       g_warning ("cannot add interfaces to invalid (non-instantiatable) type `%s'",
-		 type_descriptive_name_L (instance_type));
+		 type_descriptive_name_I (instance_type));
       return FALSE;
     }
   if (!iface || !NODE_IS_IFACE (iface))
     {
       g_warning ("cannot add invalid (non-interface) type `%s' to type `%s'",
-		 type_descriptive_name_L (iface_type),
+		 type_descriptive_name_I (iface_type),
 		 NODE_NAME (node));
       return FALSE;
     }
-  tnode = lookup_type_node_L (NODE_PARENT_TYPE (iface));
+  tnode = lookup_type_node_I (NODE_PARENT_TYPE (iface));
   if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry_L (node, tnode))
     {
       /* 2001/7/31:timj: erk, i guess this warning is junk as interface derivation is flat */
@@ -837,7 +837,7 @@ check_add_interface_L (GType instance_ty
 }
 
 static gboolean
-check_interface_info_L (TypeNode             *iface,
+check_interface_info_I (TypeNode             *iface,
 			GType                 instance_type,
 			const GInterfaceInfo *info)
 {
@@ -845,7 +845,7 @@ check_interface_info_L (TypeNode        
     {
       g_warning ("interface type `%s' for type `%s' comes without initializer",
 		 NODE_NAME (iface),
-		 type_descriptive_name_L (instance_type));
+		 type_descriptive_name_I (instance_type));
       return FALSE;
     }
   
@@ -866,7 +866,7 @@ type_data_make_W (TypeNode              
   
   if (!value_table)
     {
-      TypeNode *pnode = lookup_type_node_L (NODE_PARENT_TYPE (node));
+      TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
       
       if (pnode)
 	vtable = pnode->data->common.value_table;
@@ -974,7 +974,7 @@ type_data_ref_Wm (TypeNode *node)
 {
   if (!node->data)
     {
-      TypeNode *pnode = lookup_type_node_L (NODE_PARENT_TYPE (node));
+      TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
       GTypeInfo tmp_info;
       GTypeValueTable tmp_value_table;
       
@@ -997,7 +997,7 @@ type_data_ref_Wm (TypeNode *node)
       if (node->data)
 	INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node));
       
-      check_type_info_L (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
+      check_type_info_I (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
       type_data_make_W (node, &tmp_info,
 			check_value_table_I (NODE_NAME (node),
 					     &tmp_value_table) ? &tmp_value_table : NULL);
@@ -1045,8 +1045,8 @@ type_node_add_iface_entry_W (TypeNode *n
     if (entries[i].iface_type == iface_type)
       {
 	g_warning ("failed to add interface, type `%s' already conforms to interface type `%s'",
-		   type_descriptive_name_L (NODE_TYPE (node)),
-		   type_descriptive_name_L (iface_type));
+		   type_descriptive_name_I (NODE_TYPE (node)),
+		   type_descriptive_name_I (iface_type));
 	return;
       }
     else if (entries[i].iface_type > iface_type)
@@ -1061,7 +1061,7 @@ type_node_add_iface_entry_W (TypeNode *n
   entries[i].vtable = NULL;
   
   for (i = 0; i < node->n_children; i++)
-    type_node_add_iface_entry_W (lookup_type_node_L (node->children[i]), iface_type);
+    type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), iface_type);
 }
 
 static void
@@ -1129,7 +1129,7 @@ type_iface_add_prerequisite_W (TypeNode 
   dependants = iface_node_get_dependants_array_L (iface);
   n_dependants = dependants ? dependants[0] : 0;
   for (i = 1; i <= n_dependants; i++)
-    type_iface_add_prerequisite_W (lookup_type_node_L (dependants[i]), prerequisite_node);
+    type_iface_add_prerequisite_W (lookup_type_node_I (dependants[i]), prerequisite_node);
 }
 
 void
@@ -1143,25 +1143,24 @@ g_type_interface_add_prerequisite (GType
   g_return_if_fail (!g_type_is_a (interface_type, prerequisite_type));
   g_return_if_fail (!g_type_is_a (prerequisite_type, interface_type));
 
-  G_WRITE_LOCK (&type_rw_lock);
-  iface = lookup_type_node_L (interface_type);
-  prerequisite_node = lookup_type_node_L (prerequisite_type);
+  iface = lookup_type_node_I (interface_type);
+  prerequisite_node = lookup_type_node_I (prerequisite_type);
   if (!iface || !prerequisite_node || !NODE_IS_IFACE (iface))
     {
       g_warning ("interface type `%s' or prerequisite type `%s' invalid",
-		 type_descriptive_name_L (interface_type),
-		 type_descriptive_name_L (prerequisite_type));
-      G_WRITE_UNLOCK (&type_rw_lock);
+		 type_descriptive_name_I (interface_type),
+		 type_descriptive_name_I (prerequisite_type));
       return;
     }
+  G_WRITE_LOCK (&type_rw_lock);
   holders = iface_node_get_holders_L (iface);
   if (holders)
     {
-      g_warning ("unable to add prerequisite `%s' to interface `%s' which is already in use for `%s'",
-		 type_descriptive_name_L (prerequisite_type),
-		 type_descriptive_name_L (interface_type),
-		 type_descriptive_name_L (holders->instance_type));
       G_WRITE_UNLOCK (&type_rw_lock);
+      g_warning ("unable to add prerequisite `%s' to interface `%s' which is already in use for `%s'",
+		 type_descriptive_name_I (prerequisite_type),
+		 type_descriptive_name_I (interface_type),
+		 type_descriptive_name_I (holders->instance_type));
       return;
     }
   if (prerequisite_node->is_instantiatable)
@@ -1171,21 +1170,21 @@ g_type_interface_add_prerequisite (GType
       /* can have at most one publically installable instantiatable prerequisite */
       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
 	{
-	  TypeNode *prnode = lookup_type_node_L (IFACE_NODE_PREREQUISITES (iface)[i]);
+	  TypeNode *prnode = lookup_type_node_I (IFACE_NODE_PREREQUISITES (iface)[i]);
 
 	  if (prnode->is_instantiatable)
 	    {
 	      g_warning ("adding prerequisite `%s' to interface `%s' conflicts with existing prerequisite `%s'",
-			 type_descriptive_name_L (prerequisite_type),
-			 type_descriptive_name_L (interface_type),
-			 type_descriptive_name_L (NODE_TYPE (prnode)));
+			 type_descriptive_name_I (prerequisite_type),
+			 type_descriptive_name_I (interface_type),
+			 type_descriptive_name_I (NODE_TYPE (prnode)));
 	      G_WRITE_UNLOCK (&type_rw_lock);
 	      return;
 	    }
 	}
 
       for (i = 0; i < prerequisite_node->n_supers + 1; i++)
-	type_iface_add_prerequisite_W (iface, lookup_type_node_L (prerequisite_node->supers[i]));
+	type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisite_node->supers[i]));
     }
   else if (NODE_IS_IFACE (prerequisite_node))
     {
@@ -1195,13 +1194,13 @@ g_type_interface_add_prerequisite (GType
       dependants = iface_node_get_dependants_array_L (prerequisite_node);
       n_dependants = dependants ? dependants[0] : 0;
       for (i = 1; i <= n_dependants; i++)
-	type_iface_add_prerequisite_W (iface, lookup_type_node_L (dependants[i]));
+	type_iface_add_prerequisite_W (iface, lookup_type_node_I (dependants[i]));
       type_iface_add_prerequisite_W (iface, prerequisite_node);
     }
   else
     g_warning ("prerequisite `%s' for interface `%s' is neither instantiatable nor interface",
-	       type_descriptive_name_L (prerequisite_type),
-	       type_descriptive_name_L (interface_type));
+	       type_descriptive_name_I (prerequisite_type),
+	       type_descriptive_name_I (interface_type));
   G_WRITE_UNLOCK (&type_rw_lock);
 }
 
@@ -1235,7 +1234,7 @@ type_iface_retrive_holder_info_Wm (TypeN
       if (iholder->info)
         INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
       
-      check_interface_info_L (iface, instance_type, &tmp_info);
+      check_interface_info_I (iface, instance_type, &tmp_info);
       iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
     }
   
@@ -1276,20 +1275,18 @@ g_type_create_instance (GType type)
   GTypeClass *class;
   guint i;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
   if (!node || !node->is_instantiatable)
     {
       g_warning ("cannot create new instance of invalid (non-instantiatable) type `%s'",
-		 type_descriptive_name_U (type));
+		 type_descriptive_name_I (type));
       return NULL;
     }
   /* G_TYPE_IS_ABSTRACT() is an external call: _U */
   if (G_TYPE_IS_ABSTRACT (type))
     {
       g_warning ("cannot create instance of abstract (non-instantiatable) type `%s'",
-		 type_descriptive_name_U (type));
+		 type_descriptive_name_I (type));
       return NULL;
     }
   
@@ -1313,9 +1310,7 @@ g_type_create_instance (GType type)
     {
       TypeNode *pnode;
       
-      G_READ_LOCK (&type_rw_lock);
-      pnode = lookup_type_node_L (node->supers[i]);
-      G_READ_UNLOCK (&type_rw_lock);
+      pnode = lookup_type_node_I (node->supers[i]);
       
       if (pnode->data->instance.instance_init)
 	{
@@ -1339,17 +1334,14 @@ g_type_free_instance (GTypeInstance *ins
   
   g_return_if_fail (instance != NULL && instance->g_class != NULL);
   
-  G_READ_LOCK (&type_rw_lock);
   class = instance->g_class;
-  node = lookup_type_node_L (class->g_type);
+  node = lookup_type_node_I (class->g_type);
   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class)
     {
       g_warning ("cannot free instance of invalid (non-instantiatable) type `%s'",
-		 type_descriptive_name_L (class->g_type));
-      G_READ_UNLOCK (&type_rw_lock);
+		 type_descriptive_name_I (class->g_type));
       return;
     }
-  G_READ_UNLOCK (&type_rw_lock);
   /* G_TYPE_IS_ABSTRACT() is an external call: _U */
   if (G_TYPE_IS_ABSTRACT (NODE_TYPE (node)))
     {
@@ -1383,7 +1375,7 @@ type_propagate_iface_vtable_W (TypeNode 
   entry->vtable = vtable;
   for (i = 0; i < pnode->n_children; i++)
     {
-      TypeNode *node = lookup_type_node_L (pnode->children[i]);
+      TypeNode *node = lookup_type_node_I (pnode->children[i]);
       
       type_propagate_iface_vtable_W (node, iface, vtable);
     }
@@ -1469,7 +1461,7 @@ type_class_init_Wm (TypeNode   *node,
   
   if (pclass)
     {
-      TypeNode *pnode = lookup_type_node_L (pclass->g_type);
+      TypeNode *pnode = lookup_type_node_I (pclass->g_type);
       
       memcpy (class, pclass, pnode->data->class.class_size);
     }
@@ -1480,11 +1472,9 @@ type_class_init_Wm (TypeNode   *node,
   /* stack all base class initialization functions, so we
    * call them in ascending order.
    */
-  G_READ_LOCK (&type_rw_lock);
-  for (bnode = node; bnode; bnode = lookup_type_node_L (NODE_PARENT_TYPE (bnode)))
+  for (bnode = node; bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
     if (bnode->data->class.class_init_base)
       init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base);
-  G_READ_UNLOCK (&type_rw_lock);
   for (slist = init_slist; slist; slist = slist->next)
     {
       GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data;
@@ -1504,7 +1494,7 @@ type_class_init_Wm (TypeNode   *node,
       entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
   while (entry)
     {
-      type_iface_vtable_init_Wm (lookup_type_node_L (entry->iface_type), node);
+      type_iface_vtable_init_Wm (lookup_type_node_I (entry->iface_type), node);
       
       for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
 	if (!CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable)
@@ -1521,8 +1511,8 @@ type_data_finalize_class_ifaces_Wm (Type
   g_assert (node->is_instantiatable && node->data && node->data->class.class && node->data->common.ref_count == 0);
   
   g_message ("finalizing interfaces for %sClass `%s'",
-	     type_descriptive_name_L (G_TYPE_FUNDAMENTAL (NODE_TYPE (node))),
-	     type_descriptive_name_L (NODE_TYPE (node)));
+	     type_descriptive_name_I (G_TYPE_FUNDAMENTAL (NODE_TYPE (node))),
+	     type_descriptive_name_I (NODE_TYPE (node)));
   
   for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
     if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&
@@ -1530,7 +1520,7 @@ type_data_finalize_class_ifaces_Wm (Type
       entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
   while (entry)
     {
-      type_iface_vtable_finalize_Wm (lookup_type_node_L (entry->iface_type), node, entry->vtable);
+      type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable);
       
       for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
 	if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&
@@ -1555,15 +1545,11 @@ type_data_finalize_class_U (TypeNode  *n
    */
   if (cdata->class_finalize_base)
     cdata->class_finalize_base (class);
-  G_READ_LOCK (&type_rw_lock);
-  for (bnode = lookup_type_node_L (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_L (NODE_PARENT_TYPE (bnode)))
+  for (bnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
     if (bnode->data->class.class_finalize_base)
       {
-	G_READ_UNLOCK (&type_rw_lock);
 	bnode->data->class.class_finalize_base (class);
-	G_READ_LOCK (&type_rw_lock);
       }
-  G_READ_UNLOCK (&type_rw_lock);
   
   class->g_type = 0;
   g_free (cdata->class);
@@ -1573,14 +1559,14 @@ static void
 type_data_last_unref_Wm (GType    type,
 			 gboolean uncached)
 {
-  TypeNode *node = lookup_type_node_L (type);
+  TypeNode *node = lookup_type_node_I (type);
   
   g_return_if_fail (node != NULL && node->plugin != NULL);
   
   if (!node->data || node->data->common.ref_count == 0)
     {
       g_warning ("cannot drop last reference to unreferenced type `%s'",
-		 type_descriptive_name_U (type));
+		 type_descriptive_name_I (type));
       return;
     }
   
@@ -1642,7 +1628,7 @@ type_data_last_unref_Wm (GType    type,
       g_free (tdata);
       
       if (ptype)
-	type_data_unref_Wm (lookup_type_node_L (ptype), FALSE);
+	type_data_unref_Wm (lookup_type_node_I (ptype), FALSE);
       G_WRITE_UNLOCK (&type_rw_lock);
       g_type_plugin_unuse (node->plugin);
       G_WRITE_LOCK (&type_rw_lock);
@@ -1714,7 +1700,8 @@ g_type_register_fundamental (GType      
   
   if (!check_type_name_U (type_name))
     return 0;
-  if (G_TYPE_FUNDAMENTAL (type_id) != type_id)
+  if (type_id >= G_TYPE_FUNDAMENTAL_MAX ||
+      (type_id & G_TYPE_FLAG_RESERVED_ID_BIT) != 0)
     {
       g_warning ("cannot register fundamental type `%s' with non-fundamental id (%u)",
 		 type_name,
@@ -1729,20 +1716,20 @@ g_type_register_fundamental (GType      
       return 0;
     }
   G_WRITE_LOCK (&type_rw_lock);
-  if (lookup_type_node_L (type_id))
+  if (lookup_type_node_I (type_id))
     {
       G_WRITE_UNLOCK (&type_rw_lock);
       g_warning ("cannot register existing fundamental type `%s' (as `%s')",
-		 type_descriptive_name_U (type_id),
+		 type_descriptive_name_I (type_id),
 		 type_name);
       return 0;
     }
   
   node = type_node_fundamental_new_W (type_id, type_name, finfo->type_flags);
-  node_finfo = type_node_fundamental_info_L (node);
+  node_finfo = type_node_fundamental_info_I (node);
   type_add_flags_W (node, flags);
   
-  if (check_type_info_L (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info))
+  if (check_type_info_I (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info))
     type_data_make_W (node, info,
 		      check_value_table_I (type_name, info->value_table) ? info->value_table : NULL);
   G_WRITE_UNLOCK (&type_rw_lock);
@@ -1751,10 +1738,11 @@ g_type_register_fundamental (GType      
 }
 
 GType
-g_type_register_static (GType            parent_type,
-			const gchar     *type_name,
-			const GTypeInfo *info,
-			GTypeFlags	 flags)
+g_type_register_static_constant (GType            parent_type,
+				 const gchar     *type_name,
+				 const GTypeInfo *info,
+				 GTypeFlags	  flags,
+				 GType            opt_type)
 {
   TypeNode *pnode, *node;
   GType type = 0;
@@ -1765,7 +1753,7 @@ g_type_register_static (GType           
   g_return_val_if_fail (info != NULL, 0);
   
   if (!check_type_name_U (type_name) ||
-      !check_derivation_U (parent_type, type_name))
+      !check_derivation_I (parent_type, type_name))
     return 0;
   if (info->class_finalize)
     {
@@ -1775,11 +1763,11 @@ g_type_register_static (GType           
     }
   
   G_WRITE_LOCK (&type_rw_lock);
-  pnode = lookup_type_node_L (parent_type);
+  pnode = lookup_type_node_I (parent_type);
   type_data_ref_Wm (pnode);
-  if (check_type_info_L (pnode, G_TYPE_FUNDAMENTAL (parent_type), type_name, info))
+  if (check_type_info_I (pnode, G_TYPE_FUNDAMENTAL (parent_type), type_name, info))
     {
-      node = type_node_new_W (pnode, type_name, NULL);
+      node = type_node_new_W (pnode, type_name, NULL, opt_type);
       type_add_flags_W (node, flags);
       type = NODE_TYPE (node);
       type_data_make_W (node, info,
@@ -1791,6 +1779,15 @@ g_type_register_static (GType           
 }
 
 GType
+g_type_register_static (GType            parent_type,
+			const gchar     *type_name,
+			const GTypeInfo *info,
+			GTypeFlags	 flags)
+{
+  return g_type_register_static_constant (parent_type, type_name, info, flags, 0);
+}
+
+GType
 g_type_register_dynamic (GType        parent_type,
 			 const gchar *type_name,
 			 GTypePlugin *plugin,
@@ -1805,13 +1802,13 @@ g_type_register_dynamic (GType        pa
   g_return_val_if_fail (plugin != NULL, 0);
   
   if (!check_type_name_U (type_name) ||
-      !check_derivation_U (parent_type, type_name) ||
+      !check_derivation_I (parent_type, type_name) ||
       !check_plugin_U (plugin, TRUE, FALSE, type_name))
     return 0;
   
   G_WRITE_LOCK (&type_rw_lock);
-  pnode = lookup_type_node_L (parent_type);
-  node = type_node_new_W (pnode, type_name, plugin);
+  pnode = lookup_type_node_I (parent_type);
+  node = type_node_new_W (pnode, type_name, plugin, 0);
   type_add_flags_W (node, flags);
   type = NODE_TYPE (node);
   G_WRITE_UNLOCK (&type_rw_lock);
@@ -1831,10 +1828,10 @@ g_type_add_interface_static (GType      
   G_WRITE_LOCK (&type_rw_lock);
   if (check_add_interface_L (instance_type, interface_type))
     {
-      TypeNode *node = lookup_type_node_L (instance_type);
-      TypeNode *iface = lookup_type_node_L (interface_type);
+      TypeNode *node = lookup_type_node_I (instance_type);
+      TypeNode *iface = lookup_type_node_I (interface_type);
       
-      if (check_interface_info_L (iface, NODE_TYPE (node), info))
+      if (check_interface_info_I (iface, NODE_TYPE (node), info))
 	type_add_interface_W (node, iface, info, NULL);
     }
   G_WRITE_UNLOCK (&type_rw_lock);
@@ -1851,16 +1848,14 @@ g_type_add_interface_dynamic (GType     
   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (instance_type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (instance_type);
   if (!check_plugin_U (plugin, FALSE, TRUE, NODE_NAME (node)))
     return;
   
   G_WRITE_LOCK (&type_rw_lock);
   if (check_add_interface_L (instance_type, interface_type))
     {
-      TypeNode *iface = lookup_type_node_L (interface_type);
+      TypeNode *iface = lookup_type_node_I (interface_type);
       
       type_add_interface_W (node, iface, NULL, plugin);
     }
@@ -1877,7 +1872,7 @@ g_type_class_ref (GType type)
   /* optimize for common code path
    */
   G_WRITE_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node && node->is_classed && node->data &&
       node->data->class.class && node->data->common.ref_count > 0)
     {
@@ -1892,7 +1887,7 @@ g_type_class_ref (GType type)
     {
       G_WRITE_UNLOCK (&type_rw_lock);
       g_warning ("cannot retrive class for invalid (unclassed) type `%s'",
-		 type_descriptive_name_U (type));
+		 type_descriptive_name_I (type));
       return NULL;
     }
   
@@ -1928,13 +1923,13 @@ g_type_class_unref (gpointer g_class)
   g_return_if_fail (g_class != NULL);
   
   G_WRITE_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (class->g_type);
+  node = lookup_type_node_I (class->g_type);
   if (node && node->is_classed && node->data &&
       node->data->class.class == class && node->data->common.ref_count > 0)
     type_data_unref_Wm (node, FALSE);
   else
     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
-	       type_descriptive_name_L (class->g_type));
+	       type_descriptive_name_I (class->g_type));
   G_WRITE_UNLOCK (&type_rw_lock);
 }
 
@@ -1947,13 +1942,13 @@ g_type_class_unref_uncached (gpointer g_
   g_return_if_fail (g_class != NULL);
   
   G_WRITE_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (class->g_type);
+  node = lookup_type_node_I (class->g_type);
   if (node && node->is_classed && node->data &&
       node->data->class.class == class && node->data->common.ref_count > 0)
     type_data_unref_Wm (node, TRUE);
   else
     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
-	       type_descriptive_name_L (class->g_type));
+	       type_descriptive_name_I (class->g_type));
   G_WRITE_UNLOCK (&type_rw_lock);
 }
 
@@ -1964,7 +1959,7 @@ g_type_class_peek (GType type)
   gpointer class;
   
   G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node && node->is_classed && node->data && node->data->class.class) /* common.ref_count _may_ be 0 */
     class = node->data->class.class;
   else
@@ -1983,10 +1978,10 @@ g_type_class_peek_parent (gpointer g_cla
   g_return_val_if_fail (g_class != NULL, NULL);
   
   G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (G_TYPE_FROM_CLASS (g_class));
+  node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class));
   if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
     {
-      node = lookup_type_node_L (NODE_PARENT_TYPE (node));
+      node = lookup_type_node_I (NODE_PARENT_TYPE (node));
       class = node->data->class.class;
     }
   else
@@ -2007,17 +2002,18 @@ g_type_interface_peek (gpointer instance
   
   g_return_val_if_fail (instance_class != NULL, NULL);
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (class->g_type);
-  iface = lookup_type_node_L (iface_type);
+  node = lookup_type_node_I (class->g_type);
+  iface = lookup_type_node_I (iface_type);
   if (node && node->is_instantiatable && iface)
     {
-      IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
+      IFaceEntry *entry;
+      G_READ_LOCK (&type_rw_lock);
+      entry = type_lookup_iface_entry_L (node, iface);
+      G_READ_UNLOCK (&type_rw_lock);
       
       if (entry && entry->vtable)
 	vtable = entry->vtable;
     }
-  G_READ_UNLOCK (&type_rw_lock);
   
   return vtable;
 }
@@ -2029,9 +2025,7 @@ g_type_name (GType type)
   
   g_return_val_if_uninitialized (static_last_fundamental_id, g_type_init, NULL);
 
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
   
   return node ? NODE_NAME (node) : NULL;
 }
@@ -2041,9 +2035,7 @@ g_type_qname (GType type)
 {
   TypeNode *node;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
   
   return node ? node->qname : 0;
 }
@@ -2072,9 +2064,7 @@ g_type_parent (GType type)
 {
   TypeNode *node;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
   
   return node ? NODE_PARENT_TYPE (node) : 0;
 }
@@ -2084,13 +2074,13 @@ g_type_depth (GType type)
 {
   TypeNode *node;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
   
   return node ? node->n_supers + 1 : 0;
 }
 
+#if 0
+/* EVIL ALEX FIXME: This is bogus now. */
 GType
 g_type_next_base (GType type,
 		  GType base_type)
@@ -2099,10 +2089,10 @@ g_type_next_base (GType type,
   TypeNode *node;
   
   G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node)
     {
-      TypeNode *base_node = lookup_type_node_L (base_type);
+      TypeNode *base_node = lookup_type_node_I (base_type);
       
       if (base_node && base_node->n_supers < node->n_supers)
 	{
@@ -2116,28 +2106,44 @@ g_type_next_base (GType type,
   
   return atype;
 }
+#endif
 
 static inline gboolean
-type_node_is_a_L (TypeNode *node,
+type_node_is_a_U (TypeNode *node,
 		  TypeNode *iface_node,
 		  /*        support_inheritance */
 		  gboolean  support_interfaces,
 		  gboolean  support_prerequisites)
 {
-  if (support_interfaces &&
-      node->is_instantiatable && NODE_IS_IFACE (iface_node) &&
-      type_lookup_iface_entry_L (node, iface_node) != NULL)
-    return TRUE;
-  else if (/* support_inheritance && */
-	   iface_node->n_supers <= node->n_supers &&
-	   node->supers[node->n_supers - iface_node->n_supers] == NODE_TYPE (iface_node))
+  gboolean check_interface;
+  gboolean check_prereq;
+  gboolean res;
+  
+  if (/* support_inheritance && */
+      iface_node->n_supers <= node->n_supers &&
+      node->supers[node->n_supers - iface_node->n_supers] == NODE_TYPE (iface_node))
     return TRUE;
-  else if (support_prerequisites &&
-	   NODE_IS_IFACE (node) &&
-	   type_lookup_prerequisite_L (node, NODE_TYPE (iface_node)))
-    return TRUE;
-  else
-    return FALSE;
+
+  check_interface = support_interfaces &&
+    node->is_instantiatable && NODE_IS_IFACE (iface_node);
+  
+  check_prereq = support_prerequisites &&
+    NODE_IS_IFACE (node);
+
+  res = FALSE;
+  
+  if (check_interface || check_prereq)
+    {
+      G_READ_LOCK (&type_rw_lock);
+      if (check_interface &&
+	  type_lookup_iface_entry_L (node, iface_node) != NULL)
+	res = TRUE;
+      else if (check_prereq &&
+	       type_lookup_prerequisite_L (node, NODE_TYPE (iface_node)))
+	res = TRUE;
+      G_READ_UNLOCK (&type_rw_lock);
+    }
+  return res;
 }
 
 gboolean
@@ -2147,15 +2153,16 @@ g_type_is_a (GType type,
   TypeNode *node, *iface_node;
   gboolean is_a;
 
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  iface_node = lookup_type_node_L (iface_type);
-  is_a = node && iface_node && type_node_is_a_L (node, iface_node, TRUE, TRUE);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
+  iface_node = lookup_type_node_I (iface_type);
+  is_a = node && iface_node && type_node_is_a_U (node, iface_node, TRUE, TRUE);
 
   return is_a;
 }
 
+
+#if 0
+/* EVIL ALEX FIXME: This is bogus now */
 guint
 g_type_fundamental_branch_last (GType type)
 {
@@ -2168,6 +2175,7 @@ g_type_fundamental_branch_last (GType ty
   
   return last_type;
 }
+#endif
 
 GType* /* free result */
 g_type_children (GType  type,
@@ -2175,12 +2183,14 @@ g_type_children (GType  type,
 {
   TypeNode *node;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node)
     {
-      GType *children = g_new (GType, node->n_children + 1);
+      GType *children;
       
+      G_READ_LOCK (&type_rw_lock);
+      children = g_new (GType, node->n_children + 1);
+      
       memcpy (children, node->children, sizeof (GType) * node->n_children);
       children[node->n_children] = 0;
       
@@ -2192,7 +2202,6 @@ g_type_children (GType  type,
     }
   else
     {
-      G_READ_UNLOCK (&type_rw_lock);
       if (n_children)
 	*n_children = 0;
       
@@ -2206,12 +2215,14 @@ g_type_interfaces (GType  type,
 {
   TypeNode *node;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node && node->is_instantiatable)
     {
-      GType *ifaces = g_new (GType, CLASSED_NODE_N_IFACES (node) + 1);
+      GType *ifaces;
       guint i;
+
+      G_READ_LOCK (&type_rw_lock);
+      ifaces = g_new (GType, CLASSED_NODE_N_IFACES (node) + 1);
       
       for (i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
 	ifaces[i] = CLASSED_NODE_IFACES_ENTRIES (node)[i].iface_type;
@@ -2225,7 +2236,6 @@ g_type_interfaces (GType  type,
     }
   else
     {
-      G_READ_UNLOCK (&type_rw_lock);
       if (n_interfaces)
 	*n_interfaces = 0;
       
@@ -2285,16 +2295,15 @@ g_type_get_qdata (GType  type,
   TypeNode *node;
   gpointer data;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node)
     {
+      G_READ_LOCK (&type_rw_lock);
       data = type_get_qdata_L (node, quark);
       G_READ_UNLOCK (&type_rw_lock);
     }
   else
     {
-      G_READ_UNLOCK (&type_rw_lock);
       g_return_val_if_fail (node != NULL, NULL);
       data = NULL;
     }
@@ -2345,16 +2354,15 @@ g_type_set_qdata (GType    type,
   
   g_return_if_fail (quark != 0);
   
-  G_WRITE_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node)
     {
+      G_WRITE_LOCK (&type_rw_lock);
       type_set_qdata_W (node, quark, data);
       G_WRITE_UNLOCK (&type_rw_lock);
     }
   else
     {
-      G_WRITE_UNLOCK (&type_rw_lock);
       g_return_if_fail (node != NULL);
     }
 }
@@ -2383,8 +2391,8 @@ g_type_query (GType       type,
 
   g_return_if_fail (query != NULL);
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  G_READ_LOCK (&type_rw_lock); /* FIXME EVIL ALEX: Is this lock needed? */
+  node = lookup_type_node_I (type);
   if (node && node->is_classed && !node->plugin && node->data)
     {
       /* type is classed and static, probably even instantiatable */
@@ -2411,8 +2419,8 @@ g_type_check_flags (GType type,
   TypeNode *node;
   gboolean result = FALSE;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
+  G_READ_LOCK (&type_rw_lock); /* FIXME EVIL ALEX: Is this lock needed? */
+  node = lookup_type_node_I (type);
   if (node)
     {
       guint fflags = flags & TYPE_FUNDAMENTAL_FLAG_MASK;
@@ -2420,7 +2428,7 @@ g_type_check_flags (GType type,
       
       if (fflags)
 	{
-	  GTypeFundamentalInfo *finfo = type_node_fundamental_info_L (node);
+	  GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (node);
 	  
 	  fflags = (finfo->type_flags & fflags) == fflags;
 	}
@@ -2444,9 +2452,7 @@ g_type_get_plugin (GType type)
 {
   TypeNode *node;
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type);
   
   return node ? node->plugin : NULL;
 }
@@ -2460,12 +2466,15 @@ g_type_interface_get_plugin (GType insta
   
   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);
   
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (instance_type);  
-  iface = lookup_type_node_L (interface_type);
+  node = lookup_type_node_I (instance_type);  
+  iface = lookup_type_node_I (interface_type);
   if (node && iface)
     {
-      IFaceHolder *iholder = iface_node_get_holders_L (iface);
+      IFaceHolder *iholder;
+
+      G_READ_LOCK (&type_rw_lock);
+
+      iholder = iface_node_get_holders_L (iface);
       
       while (iholder && iholder->instance_type != instance_type)
 	iholder = iholder->next;
@@ -2474,8 +2483,6 @@ g_type_interface_get_plugin (GType insta
       if (iholder)
 	return iholder->plugin;
     }
-  else
-    G_READ_UNLOCK (&type_rw_lock);
   
   g_return_val_if_fail (node == NULL, NULL);
   g_return_val_if_fail (iface == NULL, NULL);
@@ -2507,11 +2514,9 @@ g_type_instance_is_a (GTypeInstance *typ
   if (!type_instance || !type_instance->g_class)
     return FALSE;
 
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type_instance->g_class->g_type);
-  iface = lookup_type_node_L (iface_type);
-  check = node && node->is_instantiatable && iface && type_node_is_a_L (node, iface, TRUE, FALSE);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type_instance->g_class->g_type);
+  iface = lookup_type_node_I (iface_type);
+  check = node && node->is_instantiatable && iface && type_node_is_a_U (node, iface, TRUE, FALSE);
 
   return check;
 }
@@ -2526,11 +2531,9 @@ g_type_class_is_a (GTypeClass *type_clas
   if (!type_class)
     return FALSE;
 
-  G_READ_LOCK (&type_rw_lock);
-  node = lookup_type_node_L (type_class->g_type);
-  iface = lookup_type_node_L (is_a_type);
-  check = node && node->is_classed && iface && type_node_is_a_L (node, iface, FALSE, FALSE);
-  G_READ_UNLOCK (&type_rw_lock);
+  node = lookup_type_node_I (type_class->g_type);
+  iface = lookup_type_node_I (is_a_type);
+  check = node && node->is_classed && iface && type_node_is_a_U (node, iface, FALSE, FALSE);
 
   return check;
 }
@@ -2546,31 +2549,29 @@ g_type_check_instance_cast (GTypeInstanc
 	  TypeNode *node, *iface;
 	  gboolean is_instantiatable, check;
 
-	  G_READ_LOCK (&type_rw_lock);
-	  node = lookup_type_node_L (type_instance->g_class->g_type);
+	  node = lookup_type_node_I (type_instance->g_class->g_type);
 	  is_instantiatable = node && node->is_instantiatable;
-	  iface = lookup_type_node_L (iface_type);
-	  check = is_instantiatable && iface && type_node_is_a_L (node, iface, TRUE, FALSE);
-	  G_READ_UNLOCK (&type_rw_lock);
+	  iface = lookup_type_node_I (iface_type);
+	  check = is_instantiatable && iface && type_node_is_a_U (node, iface, TRUE, FALSE);
 	  if (check)
 	    return type_instance;
 
 	  if (is_instantiatable)
 	    g_warning ("invalid cast from `%s' to `%s'",
-		       type_descriptive_name_U (type_instance->g_class->g_type),
-		       type_descriptive_name_U (iface_type));
+		       type_descriptive_name_I (type_instance->g_class->g_type),
+		       type_descriptive_name_I (iface_type));
 	  else
 	    g_warning ("invalid uninstantiatable type `%s' in cast to `%s'",
-		       type_descriptive_name_U (type_instance->g_class->g_type),
-		       type_descriptive_name_U (iface_type));
+		       type_descriptive_name_I (type_instance->g_class->g_type),
+		       type_descriptive_name_I (iface_type));
 	}
       else
 	g_warning ("invalid unclassed pointer in cast to `%s'",
-		   type_descriptive_name_U (iface_type));
+		   type_descriptive_name_I (iface_type));
     }
   else
     g_warning ("invalid cast from (NULL) pointer to `%s'",
-	       type_descriptive_name_U (iface_type));
+	       type_descriptive_name_I (iface_type));
   
   return type_instance;
 }
@@ -2584,27 +2585,25 @@ g_type_check_class_cast (GTypeClass *typ
       TypeNode *node, *iface;
       gboolean is_classed, check;
       
-      G_READ_LOCK (&type_rw_lock);
-      node = lookup_type_node_L (type_class->g_type);
+      node = lookup_type_node_I (type_class->g_type);
       is_classed = node && node->is_classed;
-      iface = lookup_type_node_L (is_a_type);
-      check = is_classed && iface && type_node_is_a_L (node, iface, FALSE, FALSE);
-      G_READ_UNLOCK (&type_rw_lock);
+      iface = lookup_type_node_I (is_a_type);
+      check = is_classed && iface && type_node_is_a_U (node, iface, FALSE, FALSE);
       if (check)
 	return type_class;
 
       if (is_classed)
 	g_warning ("invalid class cast from `%s' to `%s'",
-		   type_descriptive_name_U (type_class->g_type),
-		   type_descriptive_name_U (is_a_type));
+		   type_descriptive_name_I (type_class->g_type),
+		   type_descriptive_name_I (is_a_type));
       else
 	g_warning ("invalid unclassed type `%s' in class cast to `%s'",
-		   type_descriptive_name_U (type_class->g_type),
-		   type_descriptive_name_U (is_a_type));
+		   type_descriptive_name_I (type_class->g_type),
+		   type_descriptive_name_I (is_a_type));
     }
   else
     g_warning ("invalid class cast from (NULL) pointer to `%s'",
-	       type_descriptive_name_U (is_a_type));
+	       type_descriptive_name_I (is_a_type));
   return type_class;
 }
 
@@ -2621,15 +2620,15 @@ g_type_check_instance (GTypeInstance *ty
 	  TypeNode *node;
 	  gboolean is_instantiatable;
 	  
-	  G_READ_LOCK (&type_rw_lock);
-	  node = lookup_type_node_L (type_instance->g_class->g_type);
+	  G_READ_LOCK (&type_rw_lock); /* EVIL ALEX FIXME: Why does this lock cover the second line? Is it needed */
+	  node = lookup_type_node_I (type_instance->g_class->g_type);
 	  is_instantiatable = node && node->is_instantiatable;
 	  G_READ_UNLOCK (&type_rw_lock);
 	  if (is_instantiatable)
 	    return TRUE;
 
 	  g_warning ("instance of invalid non-instantiatable type `%s'",
-		     type_descriptive_name_U (type_instance->g_class->g_type));
+		     type_descriptive_name_I (type_instance->g_class->g_type));
 	}
       else
 	g_warning ("instance with invalid (NULL) class pointer");
@@ -2648,7 +2647,7 @@ type_check_is_value_type_U (GType type)
 
   G_READ_LOCK (&type_rw_lock);
  restart_check:
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (node)
     {
       if (node->data && node->data->common.ref_count > 0 &&
@@ -2661,7 +2660,7 @@ type_check_is_value_type_U (GType type)
 	  for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++)
 	    {
 	      GType prtype = IFACE_NODE_PREREQUISITES (node)[i];
-	      TypeNode *prnode = lookup_type_node_L (prtype);
+	      TypeNode *prnode = lookup_type_node_I (prtype);
 
 	      if (prnode->is_instantiatable)
 		{
@@ -2703,7 +2702,7 @@ g_type_value_table_peek (GType type)
   
   G_READ_LOCK (&type_rw_lock);
  restart_table_peek:
-  node = lookup_type_node_L (type);
+  node = lookup_type_node_I (type);
   if (!node)
     {
       g_warning (G_STRLOC ": type id `%u' is invalid", type);
@@ -2713,7 +2712,7 @@ g_type_value_table_peek (GType type)
   if (!node->data || node->data->common.ref_count < 1)
     {
       g_warning ("can't peek value table for type `%s' which is not currently referenced",
-		 type_descriptive_name_L (type));
+		 type_descriptive_name_I (type));
       G_READ_UNLOCK (&type_rw_lock);
       return NULL;
     }
@@ -2726,7 +2725,7 @@ g_type_value_table_peek (GType type)
       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++)
 	{
 	  GType prtype = IFACE_NODE_PREREQUISITES (node)[i];
-	  TypeNode *prnode = lookup_type_node_L (prtype);
+	  TypeNode *prnode = lookup_type_node_I (prtype);
 
 	  if (prnode->is_instantiatable)
 	    {
@@ -2822,10 +2821,6 @@ g_type_init_with_debug_flags (GTypeDebug
   /* invalid type G_TYPE_INVALID (0)
    */
   static_last_fundamental_id = 1;
-  static_type_nodes = g_renew (TypeNode**, static_type_nodes, static_last_fundamental_id);
-  static_type_nodes[0] = &type0_node;
-  static_branch_seqnos = g_renew (GType, static_branch_seqnos, static_last_fundamental_id);
-  static_branch_seqnos[0] = 1;
   
   /* void type G_TYPE_NONE
    */
Index: gobject/gtype.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gtype.h,v
retrieving revision 1.30
diff -u -p -r1.30 gtype.h
--- gobject/gtype.h	2001/08/15 09:19:52	1.30
+++ gobject/gtype.h	2001/09/05 15:13:44
@@ -26,78 +26,79 @@ G_BEGIN_DECLS
 
 /* Basic Type Macros
  */
-#define G_TYPE_FUNDAMENTAL(type)                ((type) & 0xff)
-#define	G_TYPE_FUNDAMENTAL_MAX			(0xff)
-#define G_TYPE_DERIVE_ID(ptype, branch_seqno)   (G_TYPE_FUNDAMENTAL (ptype) | ((branch_seqno) << 8))
-#define G_TYPE_BRANCH_SEQNO(type)               ((type) >> 8)
+#define G_TYPE_FUNDAMENTAL(type)                (g_type_fundamental (type))
+#define	G_TYPE_FUNDAMENTAL_MAX			(511)
+#define	G_TYPE_CONSTANT_MAX			(1023)
 #define G_TYPE_FUNDAMENTAL_LAST                 ((GType) g_type_fundamental_last ())
 
-
 /* predefined fundamental and derived types
  */
 typedef enum    /*< skip >*/
 {
   /* standard types, introduced by g_type_init() */
-  G_TYPE_INVALID,
-  G_TYPE_NONE,
-  G_TYPE_INTERFACE,
+  G_TYPE_INVALID   = 0,
+  G_TYPE_NONE      = 2,
+  G_TYPE_INTERFACE = 4,
 
   /* GLib type ids */
-  G_TYPE_CHAR,
-  G_TYPE_UCHAR,
-  G_TYPE_BOOLEAN,
-  G_TYPE_INT,
-  G_TYPE_UINT,
-  G_TYPE_LONG,
-  G_TYPE_ULONG,
-  G_TYPE_ENUM,
-  G_TYPE_FLAGS,
-  G_TYPE_FLOAT,
-  G_TYPE_DOUBLE,
-  G_TYPE_STRING,
-  G_TYPE_POINTER,
-  G_TYPE_BOXED,
-  G_TYPE_PARAM,
-  G_TYPE_OBJECT,
+  G_TYPE_CHAR     = 6,
+  G_TYPE_UCHAR    = 8,
+  G_TYPE_BOOLEAN  = 10,
+  G_TYPE_INT      = 12,
+  G_TYPE_UINT     = 14,
+  G_TYPE_LONG     = 16,
+  G_TYPE_ULONG    = 18,
+  G_TYPE_ENUM     = 20,
+  G_TYPE_FLAGS    = 22,
+  G_TYPE_FLOAT    = 24,
+  G_TYPE_DOUBLE   = 26,
+  G_TYPE_STRING   = 28,
+  G_TYPE_POINTER  = 30,
+  G_TYPE_BOXED    = 32,
+  G_TYPE_PARAM    = 34,
+  G_TYPE_OBJECT   = 36,
 
   /* reserved fundamental type ids,
    * mail gtk-devel-list redhat com for reservations
    */
-  G_TYPE_RESERVED_BSE_FIRST,
-  G_TYPE_RESERVED_BSE_LAST	= G_TYPE_RESERVED_BSE_FIRST + 15,
+  G_TYPE_RESERVED_BSE_FIRST     = 38,
+  G_TYPE_RESERVED_BSE_LAST	= G_TYPE_RESERVED_BSE_FIRST + 15*2,
   G_TYPE_RESERVED_LAST_FUNDAMENTAL,
 
   /* derived type ids */
-  G_TYPE_CLOSURE		= G_TYPE_DERIVE_ID (G_TYPE_BOXED, 1),
-  G_TYPE_VALUE			= G_TYPE_DERIVE_ID (G_TYPE_BOXED, 2),
-  G_TYPE_VALUE_ARRAY		= G_TYPE_DERIVE_ID (G_TYPE_BOXED, 3),
-  G_TYPE_GSTRING		= G_TYPE_DERIVE_ID (G_TYPE_BOXED, 4),
-  G_TYPE_PARAM_CHAR		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1),
-  G_TYPE_PARAM_UCHAR		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2),
-  G_TYPE_PARAM_BOOLEAN		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
-  G_TYPE_PARAM_INT		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 4),
-  G_TYPE_PARAM_UINT		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 5),
-  G_TYPE_PARAM_LONG		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 6),
-  G_TYPE_PARAM_ULONG		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 7),
-  G_TYPE_PARAM_UNICHAR		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 8),
-  G_TYPE_PARAM_ENUM		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 9),
-  G_TYPE_PARAM_FLAGS		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 10),
-  G_TYPE_PARAM_FLOAT		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 11),
-  G_TYPE_PARAM_DOUBLE		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 12),
-  G_TYPE_PARAM_STRING		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13),
-  G_TYPE_PARAM_PARAM		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 14),
-  G_TYPE_PARAM_BOXED		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 15),
-  G_TYPE_PARAM_POINTER		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 16),
-  G_TYPE_PARAM_VALUE_ARRAY	= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 17),
-  G_TYPE_PARAM_CLOSURE		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 18),
-  G_TYPE_PARAM_OBJECT		= G_TYPE_DERIVE_ID (G_TYPE_PARAM, 19)
+  G_TYPE_CONSTANT_TYPES = G_TYPE_FUNDAMENTAL_MAX + 1,
+  
+  G_TYPE_CLOSURE		= G_TYPE_CONSTANT_TYPES + 0,
+  G_TYPE_VALUE			= G_TYPE_CONSTANT_TYPES + 2,
+  G_TYPE_VALUE_ARRAY		= G_TYPE_CONSTANT_TYPES + 4,
+  G_TYPE_GSTRING		= G_TYPE_CONSTANT_TYPES + 6,
+  G_TYPE_PARAM_CHAR		= G_TYPE_CONSTANT_TYPES + 8,
+  G_TYPE_PARAM_UCHAR		= G_TYPE_CONSTANT_TYPES + 10,
+  G_TYPE_PARAM_BOOLEAN		= G_TYPE_CONSTANT_TYPES + 12,
+  G_TYPE_PARAM_INT		= G_TYPE_CONSTANT_TYPES + 14,
+  G_TYPE_PARAM_UINT		= G_TYPE_CONSTANT_TYPES + 16,
+  G_TYPE_PARAM_LONG		= G_TYPE_CONSTANT_TYPES + 18,
+  G_TYPE_PARAM_ULONG		= G_TYPE_CONSTANT_TYPES + 20,
+  G_TYPE_PARAM_UNICHAR		= G_TYPE_CONSTANT_TYPES + 22,
+  G_TYPE_PARAM_ENUM		= G_TYPE_CONSTANT_TYPES + 24,
+  G_TYPE_PARAM_FLAGS		= G_TYPE_CONSTANT_TYPES + 26,
+  G_TYPE_PARAM_FLOAT		= G_TYPE_CONSTANT_TYPES + 28,
+  G_TYPE_PARAM_DOUBLE		= G_TYPE_CONSTANT_TYPES + 30,
+  G_TYPE_PARAM_STRING		= G_TYPE_CONSTANT_TYPES + 32,
+  G_TYPE_PARAM_PARAM		= G_TYPE_CONSTANT_TYPES + 34,
+  G_TYPE_PARAM_BOXED		= G_TYPE_CONSTANT_TYPES + 36,
+  G_TYPE_PARAM_POINTER		= G_TYPE_CONSTANT_TYPES + 38,
+  G_TYPE_PARAM_VALUE_ARRAY	= G_TYPE_CONSTANT_TYPES + 40,
+  G_TYPE_PARAM_CLOSURE		= G_TYPE_CONSTANT_TYPES + 42,
+  G_TYPE_PARAM_OBJECT		= G_TYPE_CONSTANT_TYPES + 44
 } GTypeFundamentals;
 
 
 /* Type Checking Macros
  */
-#define G_TYPE_IS_FUNDAMENTAL(type)             (G_TYPE_BRANCH_SEQNO (type) == 0)
-#define G_TYPE_IS_DERIVED(type)                 (G_TYPE_BRANCH_SEQNO (type) > 0)
+/* EVIL FIXME: Change some of these */
+#define G_TYPE_IS_FUNDAMENTAL(type)             (type <= G_TYPE_FUNDAMENTAL_MAX)
+#define G_TYPE_IS_DERIVED(type)                 (type >  G_TYPE_FUNDAMENTAL_MAX)
 #define G_TYPE_IS_INTERFACE(type)               (G_TYPE_FUNDAMENTAL (type) == G_TYPE_INTERFACE)
 #define G_TYPE_IS_CLASSED(type)                 (g_type_check_flags ((type), G_TYPE_FLAG_CLASSED))
 #define G_TYPE_IS_INSTANTIATABLE(type)          (g_type_check_flags ((type), G_TYPE_FLAG_INSTANTIATABLE))
@@ -112,7 +113,7 @@ typedef enum    /*< skip >*/
 
 /* Typedefs
  */
-typedef guint32                         GType;
+typedef gsize                           GType;
 typedef struct _GValue                  GValue;
 typedef union  _GTypeCValue             GTypeCValue;
 typedef struct _GTypePlugin             GTypePlugin;
@@ -193,13 +194,13 @@ GType                 g_type_next_base  
 						      GType            root_type);
 gboolean              g_type_is_a                    (GType            type,
 						      GType            is_a_type);
-guint                 g_type_fundamental_branch_last (GType            type);
 gpointer              g_type_class_ref               (GType            type);
 gpointer              g_type_class_peek              (GType            type);
 void                  g_type_class_unref             (gpointer         g_class);
 gpointer              g_type_class_peek_parent       (gpointer         g_class);
 gpointer              g_type_interface_peek          (gpointer         instance_class,
 						      GType            iface_type);
+GType                 g_type_fundamental             (GType            type);
 
 /* g_free() the returned arrays */
 GType*                g_type_children                (GType            type,
@@ -349,6 +350,11 @@ gboolean	 g_type_check_value            
 gboolean	 g_type_check_value_holds	(GValue		    *value,
 						 GType		     type);
 GTypeValueTable* g_type_value_table_peek        (GType		     type);
+GType            g_type_register_static_constant (GType              parent_type,
+						  const gchar       *type_name,
+						  const GTypeInfo   *info,
+						  GTypeFlags	     flags,
+						  GType              type);
 
 
 /* --- debugging functions --- */
@@ -392,7 +398,7 @@ G_CONST_RETURN gchar* g_type_name_from_c
 #  define _G_TYPE_CIT(ip, gt)             (g_type_instance_is_a ((GTypeInstance*) ip, gt))
 #  define _G_TYPE_CCT(cp, gt)             (g_type_class_is_a ((GTypeClass*) cp, gt))
 #endif /* !__GNUC__ */
-#define	G_TYPE_FLAG_RESERVED_ID_BIT	(1 << 30)
+#define	G_TYPE_FLAG_RESERVED_ID_BIT	(1)
 extern GTypeDebugFlags			_g_type_debug_flags;
 
 G_END_DECLS







[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]