* On return the caller must check @klass for load errors.
*/
static void
-emit_class_init (MonoCompile *cfg, MonoClass *klass)
+emit_class_init (MonoCompile *cfg, MonoClass *klass, gboolean for_field_access)
{
MonoInst *vtable_arg;
int context_used;
context_used = mini_class_check_context_used (cfg, klass);
+ if (cfg->compile_aot && !for_field_access && mono_class_is_before_field_init (klass))
+ /* Only field accesses trigger initialization */
+ return;
+
if (context_used) {
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used,
klass, MONO_RGCTX_INFO_VTABLE);
* Methods with AggressiveInline flag could be inlined even if the class has a cctor.
* This might create a branch so emit it in the first code bblock instead of into initlocals_bb.
*/
- if (ip - header->code == 0 && cfg->method != method && cfg->compile_aot && (method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING) && mono_class_needs_cctor_run (method->klass, method)) {
- emit_class_init (cfg, method->klass);
- }
+ if (ip - header->code == 0 && cfg->method != method && cfg->compile_aot && (method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING) && mono_class_needs_cctor_run (method->klass, method))
+ emit_class_init (cfg, method->klass, FALSE);
if (skip_dead_blocks) {
int ip_offset = GPTRDIFF_TO_INT (ip - header->code);
* might not get called after the call was patched.
*/
if (cfg->gshared && cmethod->klass != method->klass && mono_class_is_ginst (cmethod->klass) && mono_method_is_generic_sharable (cmethod, TRUE) && mono_class_needs_cctor_run (cmethod->klass, method)) {
- emit_class_init (cfg, cmethod->klass);
+ emit_class_init (cfg, cmethod->klass, FALSE);
CHECK_TYPELOAD (cmethod->klass);
}
}
if (cfg->gshared && cmethod && cmethod->klass != method->klass && mono_class_is_ginst (cmethod->klass) && mono_method_is_generic_sharable (cmethod, TRUE) && mono_class_needs_cctor_run (cmethod->klass, method)) {
- emit_class_init (cfg, cmethod->klass);
+ emit_class_init (cfg, cmethod->klass, FALSE);
CHECK_TYPELOAD (cmethod->klass);
}
* As a workaround, we call class cctors before allocating objects.
*/
if (mini_field_access_needs_cctor_run (cfg, method, cmethod->klass, vtable) && !(g_slist_find (class_inits, cmethod->klass))) {
- emit_class_init (cfg, cmethod->klass);
+ emit_class_init (cfg, cmethod->klass, TRUE);
if (cfg->verbose_level > 2)
printf ("class %s.%s needs init call for ctor\n", m_class_get_name_space (cmethod->klass), m_class_get_name (cmethod->klass));
class_inits = g_slist_prepend (class_inits, cmethod->klass);
*/
if (mono_class_needs_cctor_run (klass, method))
- emit_class_init (cfg, klass);
+ emit_class_init (cfg, klass, TRUE);
/*
* The pointer we're computing here is
if (!addr) {
if (mini_field_access_needs_cctor_run (cfg, method, klass, vtable)) {
if (!(g_slist_find (class_inits, klass))) {
- emit_class_init (cfg, klass);
+ emit_class_init (cfg, klass, TRUE);
if (cfg->verbose_level > 2)
printf ("class %s.%s needs init call for %s\n", m_class_get_name_space (klass), m_class_get_name (klass), mono_field_get_name (field));
class_inits = g_slist_prepend (class_inits, klass);