Merge remote-tracking branch 'mfoliveira/ppc64el-v2'
[mono.git] / mono / mini / mini.c
index 6b4d8bfddad4da33b1c0fa13af219415364cdec8..b642073e91ff5d3f86b0febabd82fbe90d58a08f 100755 (executable)
@@ -53,6 +53,7 @@
 #include <mono/utils/mono-math.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-counters.h>
+#include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-logger-internal.h>
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-path.h>
@@ -710,18 +711,24 @@ G_GNUC_UNUSED gboolean
 mono_debug_count (void)
 {
        static int count = 0;
+       static gboolean inited;
+       static const char *value;
+
        count ++;
 
-       if (!g_getenv ("COUNT"))
+       if (!inited) {
+               value = g_getenv ("COUNT");
+               inited = TRUE;
+       }
+
+       if (!value)
                return TRUE;
 
-       if (count == atoi (g_getenv ("COUNT"))) {
+       if (count == atoi (value))
                break_count ();
-       }
 
-       if (count > atoi (g_getenv ("COUNT"))) {
+       if (count > atoi (value))
                return FALSE;
-       }
 
        return TRUE;
 }
@@ -1241,7 +1248,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode,
 
        if ((num + 1) >= cfg->varinfo_count) {
                int orig_count = cfg->varinfo_count;
-               cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 64;
+               cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 32;
                cfg->varinfo = (MonoInst **)g_realloc (cfg->varinfo, sizeof (MonoInst*) * cfg->varinfo_count);
                cfg->vars = (MonoMethodVar *)g_realloc (cfg->vars, sizeof (MonoMethodVar) * cfg->varinfo_count);
                memset (&cfg->vars [orig_count], 0, (cfg->varinfo_count - orig_count) * sizeof (MonoMethodVar));
@@ -4118,6 +4125,8 @@ mono_codegen (MonoCompile *cfg)
 
        cfg->code_len = code - cfg->native_code;
        cfg->prolog_end = cfg->code_len;
+       cfg->cfa_reg = cfg->cur_cfa_reg;
+       cfg->cfa_offset = cfg->cur_cfa_offset;
 
        mono_debug_open_method (cfg);
 
@@ -4132,6 +4141,7 @@ mono_codegen (MonoCompile *cfg)
                if (bb == cfg->bb_exit) {
                        cfg->epilog_begin = cfg->code_len;
                        mono_arch_emit_epilog (cfg);
+                       cfg->epilog_end = cfg->code_len;
                }
        }
 
@@ -4640,7 +4650,7 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
 
                        info = mono_jit_info_get_arch_eh_info (jinfo);
                        g_assert (info);
-                       info->epilog_size = cfg->code_size - cfg->epilog_begin;
+                       info->epilog_size = cfg->code_len - cfg->epilog_begin;
                }
                jinfo->unwind_info = unwind_desc;
                g_free (unwind_info);
@@ -4920,6 +4930,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
 #ifdef ENABLE_LLVM
        gboolean llvm = (flags & JIT_FLAG_LLVM) ? 1 : 0;
 #endif
+       static gboolean verbose_method_inited;
+       static const char *verbose_method_name;
 
        InterlockedIncrement (&mono_jit_stats.methods_compiled);
        if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION)
@@ -5000,6 +5012,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
 
        if (cfg->gen_seq_points)
                cfg->seq_points = g_ptr_array_new ();
+       mono_error_init (&cfg->error);
 
        if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container || method_is_gshared)) {
                cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED;
@@ -5070,9 +5083,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        {
                static gboolean inited;
 
-               if (!inited) {
+               if (!inited)
                        inited = TRUE;
-               }
 
                /* 
                 * Check for methods which cannot be compiled by LLVM early, to avoid
@@ -5148,8 +5160,12 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
                cfg->opt |= MONO_OPT_ABCREM;
        }
 
-       if (g_getenv ("MONO_VERBOSE_METHOD")) {
-               const char *name = g_getenv ("MONO_VERBOSE_METHOD");
+       if (!verbose_method_inited) {
+               verbose_method_name = g_getenv ("MONO_VERBOSE_METHOD");
+               verbose_method_inited = TRUE;
+       }
+       if (verbose_method_name) {
+               const char *name = verbose_method_name;
 
                if ((strchr (name, '.') > name) || strchr (name, ':')) {
                        MonoMethodDesc *desc;
@@ -5160,7 +5176,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
                        }
                        mono_method_desc_free (desc);
                } else {
-                       if (strcmp (cfg->method->name, g_getenv ("MONO_VERBOSE_METHOD")) == 0)
+                       if (strcmp (cfg->method->name, name) == 0)
                                cfg->verbose_level = 4;
                }
        }
@@ -5418,7 +5434,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        */
 
 //#define DEBUGSSA "logic_run"
-#define DEBUGSSA_CLASS "Tests"
+//#define DEBUGSSA_CLASS "Tests"
 #ifdef DEBUGSSA
 
        if (!cfg->disable_ssa) {
@@ -6087,6 +6103,10 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
        case MONO_EXCEPTION_OUT_OF_MEMORY:
                ex = mono_domain_get ()->out_of_memory_ex;
                break;
+       case MONO_EXCEPTION_MONO_ERROR:
+               g_assert (!mono_error_ok (&cfg->error));
+               ex = mono_error_convert_to_exception (&cfg->error);
+               break;
        default:
                g_assert_not_reached ();
        }
@@ -6724,14 +6744,12 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
        return runtime_invoke (obj, params, exc, info->compiled_method);
 }
 
-SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
 {
        MonoException *exc = NULL;
        MonoJitInfo *ji;
-#if !(defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32))
-       void *info = NULL;
-#endif
-       GET_CONTEXT;
+       void *info = MONO_SIG_HANDLER_GET_INFO ();
+       MONO_SIG_HANDLER_GET_CONTEXT;
 
        ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
 
@@ -6749,12 +6767,12 @@ SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
 #endif
 
        if (!ji) {
-               if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS))
+               if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
                        return;
 
                mono_handle_native_sigsegv (SIGSEGV, ctx);
                if (mono_do_crash_chaining) {
-                       mono_chain_signal (SIG_HANDLER_PARAMS);
+                       mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
                        return;
                }
        }
@@ -6762,10 +6780,10 @@ SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
        mono_arch_handle_exception (ctx, exc);
 }
 
-SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
 {
        MonoException *exc;
-       GET_CONTEXT;
+       MONO_SIG_HANDLER_GET_CONTEXT;
 
        exc = mono_get_exception_execution_engine ("SIGILL");
        
@@ -6776,13 +6794,15 @@ SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
 #define HAVE_SIG_INFO
 #endif
 
-SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
 {
        MonoJitInfo *ji;
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
        gpointer fault_addr = NULL;
-
-       GET_CONTEXT;
+#ifdef HAVE_SIG_INFO
+       MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
+#endif
+       MONO_SIG_HANDLER_GET_CONTEXT;
 
 #if defined(MONO_ARCH_SOFT_DEBUG_SUPPORTED) && defined(HAVE_SIG_INFO)
        if (mono_arch_is_single_step_event (info, ctx)) {
@@ -6804,11 +6824,11 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
 
        /* The thread might no be registered with the runtime */
        if (!mono_domain_get () || !jit_tls) {
-               if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS))
+               if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
                        return;
                mono_handle_native_sigsegv (SIGSEGV, ctx);
                if (mono_do_crash_chaining) {
-                       mono_chain_signal (SIG_HANDLER_PARAMS);
+                       mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
                        return;
                }
        }
@@ -6825,7 +6845,7 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
        if (fault_addr == NULL) {
                MonoContext mctx;
 
-               mono_arch_sigctx_to_monoctx (ctx, &mctx);
+               mono_sigctx_to_monoctx (ctx, &mctx);
 
                fault_addr = MONO_CONTEXT_GET_SP (&mctx);
        }
@@ -6841,7 +6861,7 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
                g_assert_not_reached ();
        } else {
                /* The original handler might not like that it is executed on an altstack... */
-               if (!ji && mono_chain_signal (SIG_HANDLER_PARAMS))
+               if (!ji && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
                        return;
 
                mono_arch_handle_altstack_exception (ctx, info->si_addr, FALSE);
@@ -6849,13 +6869,13 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
 #else
 
        if (!ji) {
-               if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS))
+               if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
                        return;
 
                mono_handle_native_sigsegv (SIGSEGV, ctx);
 
                if (mono_do_crash_chaining) {
-                       mono_chain_signal (SIG_HANDLER_PARAMS);
+                       mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
                        return;
                }
        }
@@ -6864,10 +6884,10 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
 #endif
 }
 
-SIG_HANDLER_FUNC (, mono_sigint_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigint_signal_handler)
 {
        MonoException *exc;
-       GET_CONTEXT;
+       MONO_SIG_HANDLER_GET_CONTEXT;
 
        exc = mono_get_exception_execution_engine ("Interrupted (SIGINT).");
        
@@ -7074,10 +7094,9 @@ mini_get_debug_options (void)
 static gpointer
 mini_create_ftnptr (MonoDomain *domain, gpointer addr)
 {
-#if !defined(__ia64__) && !defined(__ppc64__) && !defined(__powerpc64__)
+#if !defined(__ia64__) && (!defined(__ppc64__) && !defined(__powerpc64__) || _CALL_ELF == 2)
        return addr;
 #else
-
        gpointer* desc = NULL;
 
        if ((desc = g_hash_table_lookup (domain->ftnptrs_hash, addr)))
@@ -7103,7 +7122,7 @@ mini_create_ftnptr (MonoDomain *domain, gpointer addr)
 static gpointer
 mini_get_addr_from_ftnptr (gpointer descr)
 {
-#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__)
+#if defined(__ia64__) || ((defined(__ppc64__) || defined(__powerpc64__)) && _CALL_ELF != 2)
        return *(gpointer*)descr;
 #else
        return descr;
@@ -7955,6 +7974,8 @@ mono_precompile_assembly (MonoAssembly *ass, void *user_data)
                method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL);
                if (method->flags & METHOD_ATTRIBUTE_ABSTRACT)
                        continue;
+               if (method->is_generic || method->klass->generic_container)
+                       continue;
 
                count++;
                if (mini_verbose > 1) {