2008-09-11 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / mini.c
index 0545b9769555ad1e75d66ae663eba52dddd0aecf..f9aa81a3323cbd9b5af25c5d03ddf4593b0a6724 100644 (file)
@@ -174,9 +174,7 @@ static __thread gpointer mono_jit_tls MONO_TLS_FAST;
 
 MonoTraceSpec *mono_jit_trace_calls = NULL;
 gboolean mono_break_on_exc = FALSE;
-#ifndef DISABLE_AOT
 gboolean mono_compile_aot = FALSE;
-#endif
 /* If this is set, no code is generated dynamically, everything is taken from AOT files */
 gboolean mono_aot_only = FALSE;
 /* Whenever to use IMT */
@@ -221,6 +219,12 @@ gboolean check_for_pending_exc = TRUE;
 /* Whenever to disable passing/returning small valuetypes in registers for managed methods */
 gboolean disable_vtypes_in_regs = FALSE;
 
+#ifdef DISABLE_JIT
+/* Define this here, since many files reference it */
+const guint8 mono_burg_arity [MBMAX_OPCODES] = {
+};
+#endif
+
 gboolean
 mono_running_on_valgrind (void)
 {
@@ -2151,6 +2155,13 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode,
                        printf ("  Create LVAR R%d (R%d, R%d)\n", inst->dreg, inst->dreg + 1, inst->dreg + 2);
                }
 
+#ifdef MONO_ARCH_SOFT_FLOAT
+               if (cfg->opt & MONO_OPT_SSA) {
+                       if (mono_type_is_float (type))
+                               inst->flags = MONO_INST_VOLATILE;
+               }
+#endif
+
                /* Allocate a dummy MonoInst for the first vreg */
                MONO_INST_NEW (cfg, tree, OP_LOCAL);
                tree->dreg = inst->dreg + 1;
@@ -8009,7 +8020,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                        call = mono_emit_call_args (cfg, bblock, sig, NULL, FALSE, FALSE, ip, FALSE);
                                        call->inst.opcode = OP_TRAMPCALL_VTABLE;
-                                       call->fptr = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC_CLASS_INIT);
+                                       call->fptr = mono_create_generic_class_init_trampoline ();
 
                                        call->inst.inst_left = vtable;
 
@@ -8588,7 +8599,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                if (sp [2]->opcode == OP_PCONST && sp [2]->inst_p0 == NULL) {
                                        MonoInst *load;
                                        NEW_LDELEMA (cfg, load, sp, mono_defaults.object_class);
-                                       MONO_INST_NEW (cfg, ins, stelem_to_stind [*ip - CEE_STELEM_I]);
+                                       MONO_INST_NEW (cfg, ins, CEE_STIND_REF);
                                        ins->inst_left = load;
                                        ins->inst_right = sp [2];
                                        MONO_ADD_INS (bblock, ins);
@@ -9422,10 +9433,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                } else {
                                        NEW_METHODCONST (cfg, argconst, cmethod);
                                }
-                               if (method->wrapper_type != MONO_WRAPPER_SYNCHRONIZED)
-                                       temp = mono_emit_jit_icall (cfg, bblock, mono_ldftn, &argconst, ip);
-                               else
-                                       temp = mono_emit_jit_icall (cfg, bblock, mono_ldftn_nosync, &argconst, ip);
+                               temp = mono_emit_jit_icall (cfg, bblock, mono_ldftn, &argconst, ip);
                                NEW_TEMPLOAD (cfg, *sp, temp);
                                sp ++;
                                
@@ -9702,8 +9710,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                for (i = 0; i < header->num_clauses; ++i) {
                                        MonoExceptionClause *clause = &header->clauses [i];
-                                       if (MONO_OFFSET_IN_HANDLER (clause, ip - header->code) && !(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
+                                       if (MONO_OFFSET_IN_HANDLER (clause, ip - header->code) && !(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
                                                handler_offset = clause->handler_offset;
+                                               break;
+                                       }
                                }
 
                                bblock->flags |= BB_EXCEPTION_UNSAFE;
@@ -10079,7 +10089,7 @@ mono_icall_get_wrapper (MonoJitICallInfo* callinfo)
        wrapper = mono_marshal_get_icall_wrapper (callinfo->sig, name, callinfo->func, check_for_pending_exc);
        g_free (name);
 
-       trampoline = mono_create_ftnptr (domain, mono_create_jit_trampoline_in_domain (domain, wrapper, TRUE));
+       trampoline = mono_create_ftnptr (domain, mono_create_jit_trampoline_in_domain (domain, wrapper));
        mono_register_jit_icall_wrapper (callinfo, trampoline);
 
        callinfo->trampoline = trampoline;
@@ -10131,6 +10141,8 @@ compare_by_interval_start_pos_func (gconstpointer a, gconstpointer b)
                return 1;
 }
 
+#ifndef DISABLE_JIT
+
 #if 0
 #define LSCAN_DEBUG(a) do { a; } while (0)
 #else
@@ -10616,6 +10628,17 @@ mono_allocate_stack_slots (MonoCompile *m, guint32 *stack_size, guint32 *stack_a
        return mono_allocate_stack_slots_full (m, TRUE, stack_size, stack_align);
 }
 
+#else
+
+gint32*
+mono_allocate_stack_slots_full (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+#endif /* DISABLE_JIT */
+
 void
 mono_register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, gboolean no_throw)
 {
@@ -11181,7 +11204,7 @@ mono_create_tls_get (MonoCompile *cfg, int offset)
                return NULL;
        
        MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-       ins->dreg = mono_regstate_next_int (cfg->rs);
+       ins->dreg = cfg->new_ir ? mono_alloc_preg (cfg) : mono_regstate_next_int (cfg->rs);
        ins->inst_offset = offset;
        return ins;
 #else
@@ -11369,7 +11392,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                break;
        }
        case MONO_PATCH_INFO_METHOD_JUMP:
-               target = mono_create_jump_trampoline (domain, patch_info->data.method, TRUE);
+               target = mono_create_jump_trampoline (domain, patch_info->data.method, FALSE);
                break;
        case MONO_PATCH_INFO_METHOD:
                if (patch_info->data.method == method) {
@@ -11378,7 +11401,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                        /* get the trampoline to the method from the domain */
                        if (method && method->wrapper_type == MONO_WRAPPER_STATIC_RGCTX_INVOKE) {
                                target = mono_create_jit_trampoline_in_domain (mono_domain_get (),
-                                       patch_info->data.method, FALSE);
+                                       patch_info->data.method);
                        } else {
                                target = mono_create_jit_trampoline (patch_info->data.method);
                        }
@@ -11538,7 +11561,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                break;
        }
        case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
-               target = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC_CLASS_INIT);
+               target = mono_create_generic_class_init_trampoline ();
                break;
        default:
                g_assert_not_reached ();
@@ -11715,6 +11738,8 @@ mono_print_code (MonoCompile *cfg, const char* msg)
        }
 }
 
+#ifndef DISABLE_JIT
+
 extern const char * const mono_burg_rule_string [];
 
 static void
@@ -12541,8 +12566,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
                         * FIXME: Can't use the second case in methods with clauses, since the 
                         * bblocks inside the clauses are not processed during dfn computation.
                         */
-                       if ((header->clauses && (bbn && bbn->region == -1 && bbn->in_count == 0)) ||
-                               (!header->clauses && (bbn && bbn->region == -1 && !bbn->dfn))) {
+                       if (((header->clauses && (bbn && bbn->region == -1 && bbn->in_count == 0)) ||
+                                (!header->clauses && (bbn && bbn->region == -1 && !bbn->dfn))) &&
+                               bbn != cfg->bb_exit) {
                                if (cfg->verbose_level > 1)
                                        g_print ("found unreachable code in BB%d\n", bbn->block_num);
                                /* There may exist unreachable branches to this bb */
@@ -13038,6 +13064,17 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        return cfg;
 }
 
+#else
+
+MonoCompile*
+mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, gboolean compile_aot, int parts)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+#endif /* DISABLE_JIT */
+
 static MonoJitInfo*
 lookup_generic_method (MonoDomain *domain, MonoMethod *method)
 {
@@ -13997,7 +14034,7 @@ mono_runtime_install_handlers (void)
 #else /* !PLATFORM_WIN32 */
 
 
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) && !defined(__arm__)
        macosx_register_exception_handler ();
 #endif
 
@@ -14324,7 +14361,9 @@ mini_init (const char *filename, const char *runtime_version)
        mono_jit_tls_id = TlsAlloc ();
        setup_jit_tls_data ((gpointer)-1, mono_thread_abort);
 
+#ifndef DISABLE_JIT
        mono_burg_init ();
+#endif
 
        if (default_opt & MONO_OPT_AOT)
                mono_aot_init ();
@@ -14565,7 +14604,6 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_array_new_specific, "mono_array_new_specific", "object ptr int32", FALSE);
        register_icall (mono_runtime_class_init, "mono_runtime_class_init", "void ptr", FALSE);
        register_icall (mono_ldftn, "mono_ldftn", "ptr ptr", FALSE);
-       register_icall (mono_ldftn_nosync, "mono_ldftn_nosync", "ptr ptr", FALSE);
        register_icall (mono_ldvirtfn, "mono_ldvirtfn", "ptr object ptr", FALSE);
        register_icall (mono_ldvirtfn_gshared, "mono_ldvirtfn_gshared", "ptr object ptr", FALSE);
        register_icall (mono_helper_compile_generic_method, "compile_generic_method", "ptr object ptr ptr", FALSE);
@@ -14582,16 +14620,22 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_array_new_2, "mono_array_new_2", "object ptr int int", FALSE);
 #endif
 
+       mono_generic_sharing_init ();
+
+       if (mono_compile_aot)
+               /* 
+                * Avoid running managed code when AOT compiling, since the platform
+                * might only support aot-only execution.
+                */
+               mono_runtime_set_no_exec (TRUE);
+
 #define JIT_RUNTIME_WORKS
 #ifdef JIT_RUNTIME_WORKS
        mono_install_runtime_cleanup ((MonoDomainFunc)mini_cleanup);
        mono_runtime_init (domain, mono_thread_start_cb, mono_thread_attach_cb);
+       mono_thread_attach (domain);
 #endif
 
-       mono_generic_sharing_init ();
-
-       mono_thread_attach (domain);
-       
        mono_profiler_runtime_initialized ();
        
        MONO_PROBE_VES_INIT_END ();