mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 14:06:15 +01:00
31fde567a9
Classically, a GTypeInstance has had the following layout: [[[[GTypeInstance] GObject] TypeA] TypeB] [TypeAPrivate] [TypeBPrivate] where TypeB is a subclass of TypeA which is a GObject. Both TypeA and TypeB use pivate data. The main problem with this approach is that the offset between a pointer to an instance of TypeA and the TypeAPrivate is not constant: it changes depending on the depth of derivation and the size of the instance structures of the derived types. For example, changing the size of the TypeB structure in the above example would push the TypeAPrivate further along. This complicates the implementation of g_type_instance_get_private(). In particular, during object construction when the class pointer to the 'complete type' of the object is not yet stored in the header of the GTypeInstance, we need a lookup table in order to be able to implement g_type_instance_get_private() accurately. We can avoid this problem by storing the private data before the structures, in reverse order, like so: [TypeBPrivate] [TypeAPrivate] [[[[GTypeInstance] GObject] TypeA] TypeB] Now the distance between TypeA and TypeAPrivate depends only on the size of GObject and GTypeInstance, which are static. Even in the case of TypeB, the distance is not statically known but can be determined at runtime and is constant (because we will know the size of TypeAPrivate by the time we initialise TypeB and it won't change). This approach requires a slighty dirty trick: allocating extra memory _before_ the pointer we return from g_type_create_instance(). The main problem with this is that it will cause valgrind to behave very badly, reporting almost everything as "possibly lost". We can correct for this by including a few valgrind client requests in order to inform it that the start of the GTypeInstance should be considered a block of memory and that pointers to it should mean that this block is reachable. In order to make the private data reachable, we also declare it as a block and include an extra pointer from the end of the primary block pointing back at it. All of this is only done if we are running under Valgrind. https://bugzilla.gnome.org/show_bug.cgi?id=698595 |
||
---|---|---|
.. | ||
tests | ||
.gitignore | ||
ChangeLog | ||
gatomicarray.c | ||
gatomicarray.h | ||
gbinding.c | ||
gbinding.h | ||
gboxed.c | ||
gboxed.h | ||
gclosure.c | ||
gclosure.h | ||
genums.c | ||
genums.h | ||
glib-genmarshal.c | ||
glib-mkenums.in | ||
glib-types.h | ||
gmarshal.c | ||
gmarshal.h | ||
gmarshal.list | ||
gobject_probes.d | ||
gobject_trace.h | ||
gobject-query.c | ||
gobject.c | ||
gobject.h | ||
gobject.py | ||
gobject.rc.in | ||
gobject.stp.in | ||
gobjectnotifyqueue.c | ||
gparam.c | ||
gparam.h | ||
gparamspecs.c | ||
gparamspecs.h | ||
gsignal.c | ||
gsignal.h | ||
gsourceclosure.c | ||
gsourceclosure.h | ||
gtype-private.h | ||
gtype.c | ||
gtype.h | ||
gtypemodule.c | ||
gtypemodule.h | ||
gtypeplugin.c | ||
gtypeplugin.h | ||
gvalue.c | ||
gvalue.h | ||
gvaluearray.c | ||
gvaluearray.h | ||
gvaluecollector.h | ||
gvaluetransform.c | ||
gvaluetypes.c | ||
gvaluetypes.h | ||
libgobject-gdb.py.in | ||
Makefile.am | ||
makefile.msc.in | ||
marshal-genstrings.pl |