diff options
author | Zoltan Varga <vargaz@gmail.com> | 2011-03-15 01:07:57 +0300 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2011-03-16 16:43:25 +0300 |
commit | 713219d4ab15caedf59ca169feddef0117b4e718 (patch) | |
tree | 42236d5d1950673a59de3918dfba9d565822ed1a | |
parent | c0c0b38f2cfc2fc1f60c6305cde6b423ed3c98d2 (diff) |
Avoid calling class cctors during JITting when the same class needs initialization more than once during a method. Fixes #679467.
-rw-r--r-- | mono/mini/method-to-ir.c | 12 | ||||
-rw-r--r-- | mono/mini/objects.cs | 24 |
2 files changed, 31 insertions, 5 deletions
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 74e10a30e43..1da6245e548 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -8857,11 +8857,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b CHECK_TYPELOAD (klass); if (!addr) { - if (mini_field_access_needs_cctor_run (cfg, method, vtable) && !(g_slist_find (class_inits, vtable))) { - mono_emit_abs_call (cfg, MONO_PATCH_INFO_CLASS_INIT, vtable->klass, helper_sig_class_init_trampoline, NULL); - if (cfg->verbose_level > 2) - printf ("class %s.%s needs init call for %s\n", klass->name_space, klass->name, mono_field_get_name (field)); - class_inits = g_slist_prepend (class_inits, vtable); + if (mini_field_access_needs_cctor_run (cfg, method, vtable)) { + if (!(g_slist_find (class_inits, vtable))) { + mono_emit_abs_call (cfg, MONO_PATCH_INFO_CLASS_INIT, vtable->klass, helper_sig_class_init_trampoline, NULL); + if (cfg->verbose_level > 2) + printf ("class %s.%s needs init call for %s\n", klass->name_space, klass->name, mono_field_get_name (field)); + class_inits = g_slist_prepend (class_inits, vtable); + } } else { if (cfg->run_cctors) { MonoException *ex; diff --git a/mono/mini/objects.cs b/mono/mini/objects.cs index 3d849c64d05..a684d1d001a 100644 --- a/mono/mini/objects.cs +++ b/mono/mini/objects.cs @@ -1500,5 +1500,29 @@ ncells ) { return 0; } + public static bool flag; + + class B { + + internal static B[] d; + + static B () { + flag = true; + } + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + static int regress_679467_inner () { + if (flag == true) + return 1; + var o = B.d; + var o2 = B.d; + return 0; + } + + static int test_0_multiple_cctor_calls_regress_679467 () { + flag = false; + return regress_679467_inner (); + } } |