Merge pull request #2921 from lewurm/lower-typechecks-later
[mono.git] / mono / mini / mini.c
index 99b51050f1fd14ae5b5dc74f070147395b31543c..87d58290d812887d0936302d97e708acad7da54a 100644 (file)
@@ -58,6 +58,7 @@
 #include <mono/utils/mono-hwcap.h>
 #include <mono/utils/dtrace.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
 #include <mono/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -2419,7 +2420,11 @@ mono_codegen (MonoCompile *cfg)
                }
        }
 #else
-       mono_arch_patch_code (cfg, cfg->method, cfg->domain, cfg->native_code, cfg->patch_info, cfg->run_cctors);
+       mono_arch_patch_code (cfg, cfg->method, cfg->domain, cfg->native_code, cfg->patch_info, cfg->run_cctors, &cfg->error);
+       if (!is_ok (&cfg->error)) {
+               mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+               return;
+       }
 #endif
 
        if (cfg->method->dynamic) {
@@ -2891,6 +2896,17 @@ is_open_method (MonoMethod *method)
        return FALSE;
 }
 
+static void mono_insert_nop_in_empty_bb (MonoCompile *cfg)
+{
+       MonoBasicBlock *bb;
+       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+               if (bb->code)
+                       continue;
+               MonoInst *nop;
+               MONO_INST_NEW (cfg, nop, OP_NOP);
+               MONO_ADD_INS (bb, nop);
+       }
+}
 static void
 mono_create_gc_safepoint (MonoCompile *cfg, MonoBasicBlock *bblock)
 {
@@ -3494,6 +3510,12 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        MONO_TIME_TRACK (mono_jit_stats.jit_method_to_ir, i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, 0, FALSE));
        mono_cfg_dump_ir (cfg, "method-to-ir");
 
+       if (cfg->gdump_ctx != NULL) {
+               /* workaround for graph visualization, as it doesn't handle empty basic blocks properly */
+               mono_insert_nop_in_empty_bb (cfg);
+               mono_cfg_dump_ir (cfg, "mono_insert_nop_in_empty_bb");
+       }
+
        if (i < 0) {
                if (try_generic_shared && cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) {
                        if (compile_aot) {
@@ -3572,6 +3594,15 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
                mono_cfg_dump_ir (cfg, "local_cprop");
        }
 
+       if (cfg->flags & MONO_CFG_HAS_TYPE_CHECK) {
+               MONO_TIME_TRACK (mono_jit_stats.jit_decompose_typechecks, mono_decompose_typechecks (cfg));
+               if (cfg->gdump_ctx != NULL) {
+                       /* workaround for graph visualization, as it doesn't handle empty basic blocks properly */
+                       mono_insert_nop_in_empty_bb (cfg);
+               }
+               mono_cfg_dump_ir (cfg, "decompose_typechecks");
+       }
+
        /*
         * Should be done after cprop which can do strength reduction on
         * some of these ops, after propagating immediates.
@@ -4083,7 +4114,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
 
                if (method->klass->parent == mono_defaults.multicastdelegate_class) {
                        if (*name == '.' && (strcmp (name, ".ctor") == 0)) {
-                               MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("mono_delegate_ctor");
+                               MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("ves_icall_mono_delegate_ctor");
                                g_assert (mi);
                                /*
                                 * We need to make sure this wrapper
@@ -4291,8 +4322,11 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                                mono_arch_patch_code_new (NULL, target_domain, (guint8 *)tmp->data, &patch_info, target);
                        }
 #else
-                       for (tmp = jlist->list; tmp; tmp = tmp->next)
-                               mono_arch_patch_code (NULL, NULL, target_domain, tmp->data, &patch_info, TRUE);
+                       for (tmp = jlist->list; tmp; tmp = tmp->next) {
+                               mono_arch_patch_code (NULL, NULL, target_domain, tmp->data, &patch_info, TRUE, error);
+                               if (!is_ok (error))
+                                       break;
+                       }
 #endif
                }
        }