#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>
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;
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
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);
encode_patch_list (acfg, patches, patches->len, FALSE, got_offset, p, &p);
g_assert (p - buf < buf_size);
+ g_ptr_array_free (patches, TRUE);
sprintf (symbol, "%s%s_p", acfg->user_symbol_prefix, name);
if (acfg->dwarf)
mono_dwarf_writer_emit_trampoline (acfg->dwarf, symbol, symbol2, NULL, NULL, code_size, unwind_ops);
}
+
+ g_free (buf);
}
static G_GNUC_UNUSED void
offset = MONO_RGCTX_SLOT_MAKE_RGCTX (i);
mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, TRUE);
emit_trampoline (acfg, acfg->got_offset, info);
+ g_free (info);
offset = MONO_RGCTX_SLOT_MAKE_MRGCTX (i);
mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, TRUE);
emit_trampoline (acfg, acfg->got_offset, info);
+ g_free (info);
}
#ifdef MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE
}
}
+#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 */
} 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")) {
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");
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:
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
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)
g_ptr_array_add (table, new_entry);
}
}
+ g_free (chain_lengths);
//printf ("MAX: %d\n", max_chain_length);
}
emit_aot_data (acfg, MONO_AOT_TABLE_EXTRA_METHOD_INFO_OFFSETS, "extra_method_info_offsets", buf, p - buf);
+ g_free (buf);
+ g_free (info_offsets);
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)
{
// 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;
}
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);
else
encode_int16 (0, p, &p);
}
+ g_free (entry);
}
g_assert (p - buf <= buf_size);
+ g_ptr_array_free (table, TRUE);
emit_aot_data (acfg, MONO_AOT_TABLE_CLASS_NAME, "class_name_table", buf, p - buf);
+
+ g_free (buf);
}
static void
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
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));
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) {
* 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);
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");