Merge pull request #3199 from lambdageek/dev/proxy-setter
[mono.git] / mono / mini / aot-compiler.c
index 9349265c2879b8d5d29ab4119970d8c9a9078090..5719f5f1207d158d57f30b258e1595631142d73d 100644 (file)
@@ -51,6 +51,7 @@
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-rand.h>
 #include <mono/utils/json.h>
 #include <mono/utils/mono-threads-coop.h>
 
@@ -113,8 +114,8 @@ typedef struct MonoAotOptions {
        gboolean soft_debug;
        gboolean log_generics;
        gboolean log_instances;
-       gboolean gen_seq_points_file;
-       char *gen_seq_points_file_path;
+       gboolean gen_msym_dir;
+       char *gen_msym_dir_path;
        gboolean direct_pinvoke;
        gboolean direct_icalls;
        gboolean no_direct_calls;
@@ -902,7 +903,10 @@ arch_init (MonoAotCompile *acfg)
        if (acfg->aot_opts.mtriple && strstr (acfg->aot_opts.mtriple, "darwin")) {
                g_string_append (acfg->llc_args, "-mattr=+v6");
        } else {
-#ifdef ARM_FPU_VFP
+#if defined(ARM_FPU_VFP_HARD)
+               g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16 -float-abi=hard");
+               g_string_append (acfg->as_args, " -mfpu=vfp3");
+#elif defined(ARM_FPU_VFP)
                g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16");
                g_string_append (acfg->as_args, " -mfpu=vfp3");
 #else
@@ -3100,8 +3104,6 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8
                        encode_klass_ref (acfg, info->d.proxy.klass, p, &p);
                        break;
                }
-               case MONO_WRAPPER_STFLD_REMOTE:
-                       break;
                case MONO_WRAPPER_ALLOC: {
                        /* The GC name is saved once in MonoAotFileInfo */
                        g_assert (info->d.alloc.alloc_type != -1);
@@ -6689,6 +6691,11 @@ emit_trampolines (MonoAotCompile *acfg)
                        }
                }
 
+#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT
+               mono_arch_create_handler_block_trampoline (&info, TRUE);
+               emit_trampoline (acfg, acfg->got_offset, info);
+#endif
+
 #endif /* #ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES */
 
                /* Emit trampolines which are numerous */
@@ -7062,12 +7069,13 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                } else if (str_begins_with (arg, "soft-debug")) {
                        opts->soft_debug = TRUE;
                } else if (str_begins_with (arg, "gen-seq-points-file=")) {
-                       debug_options.gen_seq_points_compact_data = TRUE;
-                       opts->gen_seq_points_file = TRUE;
-                       opts->gen_seq_points_file_path = g_strdup (arg + strlen ("gen-seq-points-file="));;
+                       fprintf (stderr, "Mono Warning: aot option gen-seq-points-file= is deprecated.\n");
                } else if (str_begins_with (arg, "gen-seq-points-file")) {
-                       debug_options.gen_seq_points_compact_data = TRUE;
-                       opts->gen_seq_points_file = TRUE;
+                       fprintf (stderr, "Mono Warning: aot option gen-seq-points-file is deprecated.\n");
+               } else if (str_begins_with (arg, "msym-dir=")) {
+                       debug_options.no_seq_points_compact_data = FALSE;
+                       opts->gen_msym_dir = TRUE;
+                       opts->gen_msym_dir_path = g_strdup (arg + strlen ("msym_dir="));;
                } else if (str_begins_with (arg, "direct-pinvoke")) {
                        opts->direct_pinvoke = TRUE;
                } else if (str_begins_with (arg, "direct-icalls")) {
@@ -7135,7 +7143,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                        printf ("    tool-prefix=\n");
                        printf ("    readonly-value=\n");
                        printf ("    soft-debug\n");
-                       printf ("    gen-seq-points-file\n");
+                       printf ("    msym-dir=\n");
                        printf ("    gc-maps\n");
                        printf ("    print-skipped\n");
                        printf ("    no-instances\n");
@@ -7199,7 +7207,6 @@ can_encode_method (MonoAotCompile *acfg, MonoMethod *method)
                        case MONO_WRAPPER_STFLD:
                        case MONO_WRAPPER_LDFLD:
                        case MONO_WRAPPER_LDFLDA:
-                       case MONO_WRAPPER_STFLD_REMOTE:
                        case MONO_WRAPPER_STELEMREF:
                        case MONO_WRAPPER_ISINST:
                        case MONO_WRAPPER_PROXY_ISINST:
@@ -8237,7 +8244,7 @@ emit_llvm_file (MonoAotCompile *acfg)
                opts = g_strdup ("");
        else
 #if LLVM_API_VERSION > 100
-               opts = g_strdup ("-O2");
+               opts = g_strdup ("-O2 -disable-tail-calls");
 #else
                opts = g_strdup ("-targetlibinfo -no-aa -basicaa -notti -instcombine -simplifycfg -inline-cost -inline -sroa -domtree -early-cse -lazy-value-info -correlated-propagation -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -gvn -memdep -memcpyopt -sccp -instcombine -lazy-value-info -correlated-propagation -domtree -memdep -adce -simplifycfg -instcombine -strip-dead-prototypes -domtree -verify");
 #endif
@@ -8254,7 +8261,7 @@ emit_llvm_file (MonoAotCompile *acfg)
        if (acfg->aot_opts.llvm_only) {
                /* Use the stock clang from xcode */
                // FIXME: arch
-               command = g_strdup_printf ("clang -march=x86-64 -fpic -msse -msse2 -msse3 -msse4 -O2 -fno-optimize-sibling-calls -Wno-override-module -c -o \"%s\" \"%s.opt.bc\"", acfg->llvm_ofile, acfg->tmpbasename);
+               command = g_strdup_printf ("clang++ -fexceptions -march=x86-64 -fpic -msse -msse2 -msse3 -msse4 -O2 -fno-optimize-sibling-calls -Wno-override-module -c -o \"%s\" \"%s.opt.bc\"", acfg->llvm_ofile, acfg->tmpbasename);
 
                aot_printf (acfg, "Executing clang: %s\n", command);
                if (execute_system (command) != 0)
@@ -8875,6 +8882,21 @@ emit_extra_methods (MonoAotCompile *acfg)
        g_ptr_array_free (table, TRUE);
 }      
 
+static void
+generate_aotid (guint8* aotid)
+{
+       gpointer *rand_handle;
+       MonoError error;
+
+       mono_rand_open ();
+       rand_handle = mono_rand_init (NULL, 0);
+
+       mono_rand_try_get_bytes (rand_handle, aotid, 16, &error);
+       mono_error_assert_ok (&error);
+
+       mono_rand_close (rand_handle);
+}
+
 static void
 emit_exception_info (MonoAotCompile *acfg)
 {
@@ -8890,7 +8912,7 @@ emit_exception_info (MonoAotCompile *acfg)
 
                        // By design aot-runtime decode_exception_debug_info is not able to load sequence point debug data from a file.
                        // As it is not possible to load debug data from a file its is also not possible to store it in a file.
-                       gboolean method_seq_points_to_file = acfg->aot_opts.gen_seq_points_file &&
+                       gboolean method_seq_points_to_file = acfg->aot_opts.gen_msym_dir &&
                                cfg->gen_seq_points && !cfg->gen_sdb_seq_points;
                        gboolean method_seq_points_to_binary = cfg->gen_seq_points && !method_seq_points_to_file;
                        
@@ -8910,11 +8932,25 @@ emit_exception_info (MonoAotCompile *acfg)
        }
 
        if (seq_points_to_file) {
-               char *seq_points_aot_file = acfg->aot_opts.gen_seq_points_file_path ? acfg->aot_opts.gen_seq_points_file_path
-                       : g_strdup_printf("%s%s", acfg->image->name, SEQ_POINT_AOT_EXT);
-               mono_seq_point_data_write (&sp_data, seq_points_aot_file);
+               char *aotid = mono_guid_to_string_minimal (acfg->image->aotid);
+               char *dir = g_build_filename (acfg->aot_opts.gen_msym_dir_path, aotid, NULL);
+               char *image_basename = g_path_get_basename (acfg->image->name);
+               char *aot_file = g_strdup_printf("%s%s", image_basename, SEQ_POINT_AOT_EXT);
+               char *aot_file_path = g_build_filename (dir, aot_file, NULL);
+
+               if (g_ensure_directory_exists (aot_file_path) == FALSE) {
+                       fprintf (stderr, "AOT : failed to create msym directory: %s\n", aot_file_path);
+                       exit (1);
+               }
+
+               mono_seq_point_data_write (&sp_data, aot_file_path);
                mono_seq_point_data_free (&sp_data);
-               g_free (seq_points_aot_file);
+
+               g_free (aotid);
+               g_free (dir);
+               g_free (image_basename);
+               g_free (aot_file);
+               g_free (aot_file_path);
        }
 
        acfg->stats.offsets_size += emit_offset_table (acfg, "ex_info_offsets", MONO_AOT_TABLE_EX_INFO_OFFSETS, acfg->nmethods, 10, offsets);
@@ -9372,6 +9408,8 @@ init_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info)
        info->nshared_got_entries = acfg->nshared_got_entries;
        for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
                info->tramp_page_code_offsets [i] = acfg->tramp_page_code_offsets [i];
+
+       memcpy(&info->aotid, acfg->image->aotid, 16);
 }
 
 static void
@@ -9504,6 +9542,8 @@ emit_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info)
        for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
                emit_int32 (acfg, info->tramp_page_code_offsets [i]);
 
+       emit_bytes (acfg, info->aotid, 16);
+
        if (acfg->aot_opts.static_link) {
                emit_global_inner (acfg, acfg->static_linking_symbol, FALSE);
                emit_alignment (acfg, sizeof (gpointer));
@@ -9922,9 +9962,17 @@ compile_asm (MonoAotCompile *acfg)
                wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
 #else
        // Default (linux)
-       command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
+       char *args = g_strdup_printf ("%s %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
                wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
                wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
+
+       if (acfg->llvm) {
+               command = g_strdup_printf ("clang++ %s", args);
+       } else {
+               command = g_strdup_printf ("\"%sld\" %s", tool_prefix, args);
+       }
+       g_free (args);
+
 #endif
        aot_printf (acfg, "Executing the native linker: %s\n", command);
        if (execute_system (command) != 0) {
@@ -9948,7 +9996,7 @@ compile_asm (MonoAotCompile *acfg)
         * gas generates 'mapping symbols' each time code and data is mixed, which 
         * happens a lot in emit_and_reloc_code (), so we need to get rid of them.
         */
-       command = g_strdup_printf ("\"%sstrip\" --strip-symbol=\\$a --strip-symbol=\\$d %s", tool_prefix, tmp_outfile_name);
+       command = g_strdup_printf ("\"%sstrip\" --strip-symbol=\\$a --strip-symbol=\\$d %s", wrap_path(tool_prefix), wrap_path(tmp_outfile_name));
        aot_printf (acfg, "Stripping the binary: %s\n", command);
        if (execute_system (command) != 0) {
                g_free (tmp_outfile_name);
@@ -10397,6 +10445,12 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
 
        aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name);
 
+       generate_aotid ((guint8*) &acfg->image->aotid);
+
+       char *aotid = mono_guid_to_string (acfg->image->aotid);
+       aot_printf (acfg, "AOTID %s\n", aotid);
+       g_free (aotid);
+
 #ifndef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
        if (mono_aot_mode_is_full (&acfg->aot_opts)) {
                aot_printerrf (acfg, "--aot=full is not supported on this platform.\n");