Merge pull request #1458 from BrzVlad/feature-fat-cas
[mono.git] / mono / mini / aot-compiler.c
index ca448380128a5ed8591cd21bf41155b62d90121e..47f9497590eb3f52106abf64068c9b3176b84051 100644 (file)
@@ -216,6 +216,7 @@ typedef struct MonoAotCompile {
        char *llvm_got_symbol;
        char *plt_symbol;
        char *methods_symbol;
+       char *llvm_eh_frame_symbol;
        GHashTable *method_label_hash;
        const char *temp_prefix;
        const char *user_symbol_prefix;
@@ -1493,6 +1494,9 @@ arch_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size
        /* We clobber ECX, since EAX is used as MONO_ARCH_MONITOR_OBJECT_REG */
 #ifdef MONO_ARCH_MONITOR_OBJECT_REG
        g_assert (MONO_ARCH_MONITOR_OBJECT_REG != X86_ECX);
+#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
+       g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG != X86_ECX);
+#endif
 #endif
 
        code = buf;
@@ -3046,6 +3050,7 @@ is_plt_patch (MonoJumpInfo *patch_info)
        case MONO_PATCH_INFO_RGCTX_FETCH:
        case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
        case MONO_PATCH_INFO_MONITOR_ENTER:
+       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
        case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
                return TRUE;
@@ -3452,8 +3457,6 @@ add_wrappers (MonoAotCompile *acfg)
        }
 
        if (strcmp (acfg->image->assembly->aname.name, "mscorlib") == 0) {
-               MonoMethodDesc *desc;
-               MonoMethod *orig_method;
                int nallocators;
 
                /* Runtime invoke wrappers */
@@ -3530,25 +3533,6 @@ add_wrappers (MonoAotCompile *acfg)
                                if (m)
                                        add_method (acfg, m);
                        }
-
-                       /* Monitor Enter/Exit */
-                       desc = mono_method_desc_new ("Monitor:Enter(object,bool&)", FALSE);
-                       orig_method = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
-                       /* This is a v4 method */
-                       if (orig_method) {
-                               method = mono_monitor_get_fast_path (orig_method);
-                               if (method)
-                                       add_method (acfg, method);
-                       }
-                       mono_method_desc_free (desc);
-
-                       desc = mono_method_desc_new ("Monitor:Exit(object)", FALSE);
-                       orig_method = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
-                       g_assert (orig_method);
-                       mono_method_desc_free (desc);
-                       method = mono_monitor_get_fast_path (orig_method);
-                       if (method)
-                               add_method (acfg, method);
                }
 
                /* Stelemref wrappers */
@@ -3567,22 +3551,6 @@ add_wrappers (MonoAotCompile *acfg)
                /* isinst_with_check wrapper */
                add_method (acfg, mono_marshal_get_isinst_with_cache ());
 
-#if defined(MONO_ARCH_ENABLE_MONITOR_IL_FASTPATH)
-               {
-                       MonoMethodDesc *desc;
-                       MonoMethod *m;
-
-                       desc = mono_method_desc_new ("Monitor:Enter(object,bool&)", FALSE);
-                       m = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
-                       mono_method_desc_free (desc);
-                       if (m) {
-                               m = mono_monitor_get_fast_path (m);
-                               if (m)
-                                       add_method (acfg, m);
-                       }
-               }
-#endif
-
                /* JIT icall wrappers */
                /* FIXME: locking - this is "safe" as full-AOT threads don't mutate the icall hash*/
                g_hash_table_foreach (mono_get_jit_icall_info (), add_jit_icall_wrapper, acfg);
@@ -5207,6 +5175,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
        }
        case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
        case MONO_PATCH_INFO_MONITOR_ENTER:
+       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
        case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_SEQ_POINT_INFO:
                break;
@@ -5779,39 +5748,49 @@ get_plt_entry_debug_sym (MonoAotCompile *acfg, MonoJumpInfo *ji, GHashTable *cac
 {
        char *debug_sym = NULL;
        char *s;
+       char *prefix;
+
+       if (acfg->llvm_separate && llvm_acfg->aot_opts.static_link) {
+               /* Need to add a prefix to create unique symbols */
+               prefix = g_strdup_printf ("plt_%s_", acfg->assembly_name_sym);
+       } else {
+               prefix = g_strdup ("plt_");
+       }
 
        switch (ji->type) {
        case MONO_PATCH_INFO_METHOD:
-               debug_sym = get_debug_sym (ji->data.method, "plt_", cache);
+               debug_sym = get_debug_sym (ji->data.method, prefix, cache);
                break;
        case MONO_PATCH_INFO_INTERNAL_METHOD:
-               debug_sym = g_strdup_printf ("plt__jit_icall_%s", ji->data.name);
+               debug_sym = g_strdup_printf ("%s_jit_icall_%s", prefix, ji->data.name);
                break;
        case MONO_PATCH_INFO_CLASS_INIT:
                s = mono_type_get_name (&ji->data.klass->byval_arg);
-               debug_sym = g_strdup_printf ("plt__class_init_%s", s);
+               debug_sym = g_strdup_printf ("%s__class_init_%s", prefix, s);
                g_free (s);
                break;
        case MONO_PATCH_INFO_RGCTX_FETCH:
-               debug_sym = g_strdup_printf ("plt__rgctx_fetch_%d", acfg->label_generator ++);
+               debug_sym = g_strdup_printf ("%s_rgctx_fetch_%d", prefix, acfg->label_generator ++);
                break;
        case MONO_PATCH_INFO_ICALL_ADDR: {
                char *s = get_debug_sym (ji->data.method, "", cache);
                
-               debug_sym = g_strdup_printf ("plt__icall_native_%s", s);
+               debug_sym = g_strdup_printf ("%s_icall_native_%s", prefix, s);
                g_free (s);
                break;
        }
        case MONO_PATCH_INFO_JIT_ICALL_ADDR:
-               debug_sym = g_strdup_printf ("plt__jit_icall_native_%s", ji->data.name);
+               debug_sym = g_strdup_printf ("%s_jit_icall_native_%s", prefix, ji->data.name);
                break;
        case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
-               debug_sym = g_strdup_printf ("plt__generic_class_init");
+               debug_sym = g_strdup_printf ("%s_generic_class_init", prefix);
                break;
        default:
                break;
        }
 
+       g_free (prefix);
+
        return sanitize_symbol (acfg, debug_sym);
 }
 
@@ -6102,8 +6081,12 @@ emit_trampolines (MonoAotCompile *acfg)
                mono_arch_get_nullified_class_init_trampoline (&info);
                emit_trampoline (acfg, acfg->got_offset, info);
 #if defined(MONO_ARCH_MONITOR_OBJECT_REG)
-               mono_arch_create_monitor_enter_trampoline (&info, TRUE);
+               mono_arch_create_monitor_enter_trampoline (&info, FALSE, TRUE);
                emit_trampoline (acfg, acfg->got_offset, info);
+#if defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
+               mono_arch_create_monitor_enter_trampoline (&info, TRUE, TRUE);
+               emit_trampoline (acfg, acfg->got_offset, info);
+#endif
                mono_arch_create_monitor_exit_trampoline (&info, TRUE);
                emit_trampoline (acfg, acfg->got_offset, info);
 #endif
@@ -7201,7 +7184,7 @@ emit_llvm_file (MonoAotCompile *acfg)
                g_string_append_printf (acfg->llc_args, " -mtriple=%s", acfg->aot_opts.mtriple);
 
        if (acfg->llvm_separate)
-               g_string_append_printf (acfg->llc_args, " -mono-eh-frame-symbol=mono_eh_frame");
+               g_string_append_printf (acfg->llc_args, " -mono-eh-frame-symbol=%s", acfg->llvm_eh_frame_symbol);
 
 #if defined(TARGET_MACH) && defined(TARGET_ARM)
        /* ios requires PIC code now */
@@ -8093,7 +8076,7 @@ emit_globals (MonoAotCompile *acfg)
        int i, table_size;
        guint32 hash;
        GPtrArray *table;
-       char symbol [256];
+       char symbol [1024];
        GlobalsTableEntry *entry, *new_entry;
 
        if (!acfg->aot_opts.static_link)
@@ -8187,6 +8170,7 @@ emit_globals (MonoAotCompile *acfg)
                sprintf (symbol, "name_%d", i);
                emit_pointer (acfg, symbol);
 
+               g_assert (strlen (name) < sizeof (symbol));
                sprintf (symbol, "%s", name);
                emit_pointer (acfg, symbol);
        }
@@ -8286,7 +8270,7 @@ emit_file_info (MonoAotCompile *acfg)
                /*
                 * Emit a reference to the mono_eh_frame table created by our modified LLVM compiler.
                 */
-               emit_pointer (acfg, "mono_eh_frame");
+               emit_pointer (acfg, acfg->llvm_eh_frame_symbol);
        } else {
                emit_pointer (acfg, NULL);
        }
@@ -8980,22 +8964,21 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
 
                mini_llvm_init ();
 
-               if (!acfg->aot_opts.static_link && (!acfg->aot_opts.asm_only || acfg->aot_opts.llvm_outfile)) {
+               if (!acfg->aot_opts.asm_only || acfg->aot_opts.llvm_outfile) {
                        /*
                         * Emit all LLVM code into a separate assembly/object file and link with it
                         * normally.
-                        * FIXME:
-                        * Can't use it when using asm_only or static_link, since it requires changes
-                        * to users because we generate two files now. Also, symbol names have to be
-                        * prefixed by a unique prefix so multiple files can be linked together.
-                        * This also affects the mono_eh_frame symbol emitted by LLVM.
                         */
-#if LLVM_API_VERSION >= 3 && (defined(TARGET_AMD64) || defined(TARGET_X86))
+#if LLVM_API_VERSION >= 3
                        acfg->llvm_separate = TRUE;
                        if (!acfg->aot_opts.asm_only)
                                acfg->llvm_owriter = TRUE;
 #endif
                }
+               if (acfg->aot_opts.llvm_outfile && !acfg->llvm_separate) {
+                       aot_printerrf (acfg, "The llvm-outputfile= option is not supported on this platform.\n");
+                       return 1;
+               }
        }
 
        if (acfg->aot_opts.full_aot)
@@ -9037,8 +9020,13 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        acfg->plt_symbol = g_strdup_printf ("%smono_aot_%s_plt", acfg->llvm_label_prefix, acfg->assembly_name_sym);
 
        acfg->got_symbol = g_strdup_printf ("%s%s", acfg->llvm_label_prefix, acfg->got_symbol_base);
-       if (acfg->llvm)
+       if (acfg->llvm) {
                acfg->llvm_got_symbol = g_strdup_printf ("%s%s", acfg->llvm_label_prefix, acfg->llvm_got_symbol_base);
+               if (acfg->llvm_separate)
+                       acfg->llvm_eh_frame_symbol = g_strdup_printf ("mono_aot_%s_eh_frame", acfg->assembly_name_sym);
+               else
+                       acfg->llvm_eh_frame_symbol = g_strdup ("mono_eh_frame");
+       }
 
        acfg->method_index = 1;