Question about how gobject manage class's memory

Hi.
I’m totally new on gobject.
So I’m following gobject tutorial, and I wondered how gobject managing parent class’s pointer like below.

...
static void
viewer_file_dispose (GObject *gobject)
{
  ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
  g_clear_object (&priv->input_stream);
  G_OBJECT_CLASS (viewer_file_parent_class)->dispose (gobject);
}
static void
viewer_file_class_init (ViewerFileClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  object_class->dispose = viewer_file_dispose;
...

If I understood well, viewer_file_parent_class isn’t equal ViewerFileClass *klass->parent_class.
At this point, I wondered how gobject set and get the single parent class pointer.
So I searched gtype.c codes and I found the function “lookup_type_node_I”

...
static inline TypeNode*
lookup_type_node_I (register GType utype)
{
  if (utype > G_TYPE_FUNDAMENTAL_MAX)
    return (TypeNode*) (utype & ~TYPE_ID_MASK);
  else
    return static_fundamental_type_nodes[utype >> G_TYPE_FUNDAMENTAL_SHIFT];
}
...

This codes seems TypeNode has fixed memory address along Gtype value “utype”.
But I cannot understand how that can be possiable.
As short I want to ask how gobject set and get TypeNode pointer.
Thanks for reading.

Regards.

viewer_file_parent_class refers to parent class data in the parent
type while klass->parent_class refers to parent class data in the
actual type. They are not the same.

Consider this code:

typedef struct MyObject {
    GObject parent_object;
};
typedef struct MyObjectClass {
    GObjectClass parent_class;
};

/* The parent class of MyObject is GObject */
static my_object_parent_class = (GObjectClass *) g_type_class_peek(G_TYPE_OBJECT);

static void
my_object_dispose(MyObject *object)
{
    /* ... my dispose code here ... */
    /* Chain up GObject::dispose() */
    my_object_parent_class->dispose((GObject *) object);
}

static void
my_object_class_init(MyObjectClass *klass)
{
    ((GObjectClass *) klass)->dispose = my_dispose;
}

This is functionally similar to what happens with G_DEFINE_TYPE and
friends.

If you look closely, you’ll see that klass->parent_class (or the
equivalent (GObjectClass *) klass or G_OBJECT_CLASS(klass)) contains
the GObjectClass fields specific to MyObject, while
my_object_parent_class contains the GObjectClass fields specific to
GObject.

This means, for example, that klass->parent_class.dispose() (or the
equivalent G_OBJECT_CLASS(klass)->dispose()) calls
MyObject::dispose() while my_object_parent_class->dispose() calls
GObject::dispose(). This, as shown in the above example, is often
used to chain up the parent methods.

GType has conceptually nothing to do with the above. I personally
consider them as indexes in a register that contains type specific
metadata (and one of them is the above class data).