-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Description
Code sample
The code for the latest iteration of this design is in #7857
Summary of design
We would like to add an overall notion of "MonoClass readiness" to replace the various MonoClass:*_inited bitfields. This PR does not do that. But it adds the corresponding
change to the loading API:
typedef enum _MonoClassReady {
/* Barebones readiness: just allocate a MonoClass and set its image, name and name space. */
MONO_CLASS_READY_BAREBONES = 0,
/* Instantiate readiness: metadata vtable is initialized, ready to create runtime vtables. */
MONO_CLASS_READY_INSTANTIATE = 0xff,
MONO_CLASS_READY_MIN = MONO_CLASS_READY_BAREBONES,
MONO_CLASS_READY_MAX = MONO_CLASS_READY_INSTANTIATE,
} MonoClassReady;
gboolean
mono_class_init_ready (MonoClass *klass, MonoClassReady readiness);-
We would eventually add multiple readiness levels between
MINandMAXthat represent aMonoClassthat is partially initialized. (I don't know precisely how many we will need, so the examples below should not be taken too seriously.) For example:-
Some information about a class is collected from its parent. For example
MonoClass:delegateis set based on the value of the parent. So we may haveMONO_CLASS_READY_PARENTaboveMONO_CLASS_READY_BAREBONESto signal that the parent class is ready to provide that information. (This is inmono_class_setup_parenttoday and its protected by the loader lock and thegclass_recorded_listin the generic instance case). -
Instance size information is currently guarded by
MonoClass:size_inited. We would add a
MONO_CLASS_READY_INSTANCE_SIZEaboveMONO_CLASS_READY_PARENTand belowMONO_CLASS_READY_INSTANTIATE.
-
-
The semantics of
mono_class_init_ready (klass, level)is that it is a no-op ifklassis already
ready at levellevelor higher, otherwise it will perform whatever initialization is needed to bring the class from its current level up to at least the requested level. -
Eventually the various legacy initialization functions (see
mono/metadata/class-init.h- e.g.mono_class_init_sizes,mono_class_layout_fields, etc) will be removed (or markedMONO_RT_EXTERNAL_ONLY) and there will be a single initialization entrypoint. -
This only covers the "essential" fields of a MonoClass, those that directly contribute to creating a valid runtime instance of the class. Essential fields are initialized at some readiness level and are valid at that level or higher.
For example:
type_tokenandimageare essential fields at the barebones level.delegateis an essential field at the 'parent known' level.We also have several "synthetic" fields, those that represent information that can be derived from the essential fields but that we choose to cache in the
MonoClassfor efficiency. Synthetic fields will continue to use a bit or a sentinel value (non-NULL == initialized) to guard the value. Initializing a synthetic field may require the class to be in a certain readiness level, but it is valid for a class at that level not to have the synthetic field initialized.For example:
superclassesis a synthetic field, guarded by a non-NULL value, used for fast "is subclass of" queries that requires the parent of a class to be known, but a call tomono_class_init_read (klass, MONO_CLASS_READY_PARENT)does not causesuperclassesto become initialized.
Discussion summary
(I will edit this part to collect discussion comments)
- Some of the init steps are orthogonal, so there's a lattice of readiness levels.
- we should have explicit pre-constructed and post-unloading levels to mark invalid uses - [RFC] mono_class_init_ready #7856 (comment)
TODOs
(I will edit this part to collect actionable discussion comments)
- Use
BEGIN/FINAL(like coreclr) instead ofMIN/MAX - Define mono_class_init_ready and MIN and MAX readiness levels #7857 (comment) - rename
INSTANTIATEfor now sincemono_class_initdoesn't initialize the vtable today, so it's misleading. -
MonoClassReadinessinstead ofMonoClassReady.
The code for the current iteration of this design is in #7857