-/*
- * aot-compiler.c: mono Ahead of Time compiler
+/**
+ * \file
+ * mono Ahead of Time compiler
*
* Author:
* Dietmar Maurer (dietmar@ximian.com)
#include <mono/utils/json.h>
#include <mono/utils/mono-threads-coop.h>
#include <mono/profiler/mono-profiler-aot.h>
-#include <mono/io-layer/io-layer.h>
+#include <mono/utils/w32api.h>
#include "aot-compiler.h"
#include "seq-points.h"
guint32 label_generator;
gboolean llvm;
gboolean has_jitted_code;
+ gboolean is_full_aot;
MonoAotFileFlags flags;
MonoDynamicStream blob;
gboolean blob_closed;
va_end (args);
mono_error_cleanup (error);
- g_error ("FullAOT cannot continue if there are loader errors");
+ if (acfg->is_full_aot) {
+ fprintf (output, "FullAOT cannot continue if there are loader errors.\n");
+ exit (1);
+ }
}
/* Wrappers around the image writer functions */
named += slen;
}
- wrapper = mono_marshal_get_managed_wrapper (method, klass, 0);
+ wrapper = mono_marshal_get_managed_wrapper (method, klass, 0, &error);
+ mono_error_assert_ok (&error);
+
add_method (acfg, wrapper);
if (export_name)
g_hash_table_insert (acfg->export_names, wrapper, export_name);
if (il_offset == -1 || il_offset == prev_il_offset)
continue;
prev_il_offset = il_offset;
- loc = mono_debug_symfile_lookup_location (minfo, il_offset);
+ loc = mono_debug_method_lookup_location (minfo, il_offset);
if (!(loc && loc->source_file))
continue;
if (loc->row == prev_line) {
- mono_debug_symfile_free_location (loc);
+ mono_debug_free_source_location (loc);
continue;
}
prev_line = loc->row;
options = "";
prologue_end = TRUE;
fprintf (acfg->fp, ".loc %d %d 0%s\n", findex, loc->row, options);
- mono_debug_symfile_free_location (loc);
+ mono_debug_free_source_location (loc);
}
skip = FALSE;
opts->write_symbols = TRUE;
} else if (str_begins_with (arg, "no-write-symbols")) {
opts->write_symbols = FALSE;
+ // Intentionally undocumented -- one-off experiment
} else if (str_begins_with (arg, "metadata-only")) {
opts->metadata_only = TRUE;
} else if (str_begins_with (arg, "bind-to-runtime-version")) {
opts->nodebug = TRUE;
} else if (str_begins_with (arg, "dwarfdebug")) {
opts->dwarf_debug = TRUE;
+ // Intentionally undocumented -- No one remembers what this does. It appears to be ARM-only
} else if (str_begins_with (arg, "nopagetrampolines")) {
opts->use_trampolines_page = FALSE;
} else if (str_begins_with (arg, "ntrampolines=")) {
opts->ld_flags = g_strdup (arg + strlen ("ld-flags="));
} else if (str_begins_with (arg, "soft-debug")) {
opts->soft_debug = TRUE;
+ // Intentionally undocumented x2-- deprecated
} else if (str_begins_with (arg, "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")) {
opts->print_skipped_methods = TRUE;
} else if (str_begins_with (arg, "stats")) {
opts->stats = TRUE;
+ // Intentionally undocumented-- has no known function other than to debug the compiler
} else if (str_begins_with (arg, "no-instances")) {
opts->no_instances = TRUE;
+ // Intentionally undocumented x4-- Used for internal debugging of compiler
} else if (str_begins_with (arg, "log-generics")) {
opts->log_generics = TRUE;
} else if (str_begins_with (arg, "log-instances=")) {
} else if (str_begins_with (arg, "info")) {
printf ("AOT target setup: %s.\n", AOT_TARGET_STR);
exit (0);
+ // Intentionally undocumented: Used for precise stack maps, which are not available yet
} else if (str_begins_with (arg, "gc-maps")) {
mini_gc_enable_gc_maps_for_aot ();
+ // Intentionally undocumented: Used for internal debugging
} else if (str_begins_with (arg, "dump")) {
opts->dump_json = TRUE;
} else if (str_begins_with (arg, "llvmonly")) {
opts->verbose = TRUE;
} else if (str_begins_with (arg, "help") || str_begins_with (arg, "?")) {
printf ("Supported options for --aot:\n");
- printf (" outfile=\n");
- printf (" llvm-outfile=\n");
- printf (" llvm-path=\n");
- printf (" temp-path=\n");
- printf (" save-temps\n");
- printf (" keep-temps\n");
- printf (" write-symbols\n");
- printf (" metadata-only\n");
+ printf (" asmonly\n");
printf (" bind-to-runtime-version\n");
+ printf (" bitcode\n");
+ printf (" data-outfile=\n");
+ printf (" direct-icalls\n");
+ printf (" direct-pinvoke\n");
+ printf (" dwarfdebug\n");
printf (" full\n");
- printf (" threads=\n");
- printf (" static\n");
- printf (" asmonly\n");
- printf (" asmwriter\n");
+ printf (" hybrid\n");
+ printf (" info\n");
+ printf (" keep-temps\n");
+ printf (" llvm\n");
+ printf (" llvmonly\n");
+ printf (" llvm-outfile=\n");
+ printf (" llvm-path=\n");
+ printf (" msym-dir=\n");
+ printf (" mtriple\n");
+ printf (" nimt-trampolines=\n");
printf (" nodebug\n");
- printf (" dwarfdebug\n");
- printf (" ntrampolines=\n");
+ printf (" no-direct-calls\n");
+ printf (" no-write-symbols\n");
printf (" nrgctx-trampolines=\n");
- printf (" nimt-trampolines=\n");
+ printf (" nrgctx-fetch-trampolines=\n");
printf (" ngsharedvt-trampolines=\n");
- printf (" tool-prefix=\n");
+ printf (" ntrampolines=\n");
+ printf (" outfile=\n");
+ printf (" profile=\n");
+ printf (" profile-only\n");
+ printf (" print-skipped-methods\n");
printf (" readonly-value=\n");
+ printf (" save-temps\n");
printf (" soft-debug\n");
- printf (" msym-dir=\n");
- printf (" gc-maps\n");
- printf (" print-skipped\n");
- printf (" no-instances\n");
+ printf (" static\n");
printf (" stats\n");
- printf (" dump\n");
- printf (" info\n");
+ printf (" temp-path=\n");
+ printf (" tool-prefix=\n");
+ printf (" threads=\n");
+ printf (" write-symbols\n");
printf (" verbose\n");
printf (" help/?\n");
exit (0);
return;
}
if (cfg->exception_type != MONO_EXCEPTION_NONE) {
- if (acfg->aot_opts.print_skipped_methods)
- printf ("Skip (JIT failure): %s\n", mono_method_get_full_name (method));
+ /* Some instances cannot be JITted due to constraints etc. */
+ if (!method->is_inflated)
+ report_loader_error (acfg, &cfg->error, "Unable to compile method '%s' due to: '%s'.\n", mono_method_get_full_name (method), mono_error_get_message (&cfg->error));
/* Let the exception happen at runtime */
return;
}
static mono_thread_start_return_t WINAPI
compile_thread_main (gpointer user_data)
{
- MonoDomain *domain = ((MonoDomain **)user_data) [0];
- MonoAotCompile *acfg = ((MonoAotCompile **)user_data) [1];
- GPtrArray *methods = ((GPtrArray **)user_data) [2];
+ MonoAotCompile *acfg = ((MonoAotCompile **)user_data) [0];
+ GPtrArray *methods = ((GPtrArray **)user_data) [1];
int i;
MonoError error;
- MonoThread *thread = mono_thread_attach (domain);
- mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "AOT compiler"), TRUE, &error);
+ MonoInternalThread *internal = mono_thread_internal_current ();
+ mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "AOT compiler"), TRUE, FALSE, &error);
mono_error_assert_ok (&error);
for (i = 0; i < methods->len; ++i)
return TRUE;
}
-/*
- * mono_aot_get_mangled_method_name:
- *
- * Return a unique mangled name for METHOD, or NULL.
- */
-char*
-mono_aot_get_mangled_method_name (MonoMethod *method)
+static void
+append_mangled_wrapper_type (GString *s, guint32 wrapper_type)
{
- WrapperInfo *info;
- GString *s;
- gboolean supported;
+ const char *label;
- // FIXME: Add more cases
- if (method->wrapper_type != MONO_WRAPPER_UNKNOWN)
- return NULL;
- info = mono_marshal_get_wrapper_info (method);
- if (!(info && (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG || info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG)))
- return NULL;
+ switch (wrapper_type) {
+ case MONO_WRAPPER_REMOTING_INVOKE:
+ label = "remoting_invoke";
+ break;
+ case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK:
+ label = "remoting_invoke_check";
+ break;
+ case MONO_WRAPPER_XDOMAIN_INVOKE:
+ label = "remoting_invoke_xdomain";
+ break;
+ case MONO_WRAPPER_PROXY_ISINST:
+ label = "proxy_isinst";
+ break;
+ case MONO_WRAPPER_LDFLD:
+ label = "ldfld";
+ break;
+ case MONO_WRAPPER_LDFLDA:
+ label = "ldflda";
+ break;
+ case MONO_WRAPPER_STFLD:
+ label = "stfld";
+ break;
+ case MONO_WRAPPER_ALLOC:
+ label = "alloc";
+ break;
+ case MONO_WRAPPER_WRITE_BARRIER:
+ label = "write_barrier";
+ break;
+ case MONO_WRAPPER_STELEMREF:
+ label = "stelemref";
+ break;
+ case MONO_WRAPPER_UNKNOWN:
+ label = "unknown";
+ break;
+ case MONO_WRAPPER_MANAGED_TO_NATIVE:
+ label = "man2native";
+ break;
+ case MONO_WRAPPER_SYNCHRONIZED:
+ label = "synch";
+ break;
+ case MONO_WRAPPER_MANAGED_TO_MANAGED:
+ label = "man2man";
+ break;
+ case MONO_WRAPPER_CASTCLASS:
+ label = "castclass";
+ break;
+ case MONO_WRAPPER_RUNTIME_INVOKE:
+ label = "run_invoke";
+ break;
+ case MONO_WRAPPER_DELEGATE_INVOKE:
+ label = "del_inv";
+ break;
+ case MONO_WRAPPER_DELEGATE_BEGIN_INVOKE:
+ label = "del_beg_inv";
+ break;
+ case MONO_WRAPPER_DELEGATE_END_INVOKE:
+ label = "del_end_inv";
+ break;
+ case MONO_WRAPPER_NATIVE_TO_MANAGED:
+ label = "native2man";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
- s = g_string_new ("");
+ g_string_append_printf (s, "%s_", label);
+}
- g_string_append_printf (s, "aot_method_w_");
+static void
+append_mangled_wrapper_subtype (GString *s, WrapperSubtype subtype)
+{
+ const char *label;
- switch (info->subtype) {
+ switch (subtype)
+ {
+ case WRAPPER_SUBTYPE_NONE:
+ return;
+ case WRAPPER_SUBTYPE_ELEMENT_ADDR:
+ label = "elem_addr";
+ break;
+ case WRAPPER_SUBTYPE_STRING_CTOR:
+ label = "str_ctor";
+ break;
+ case WRAPPER_SUBTYPE_VIRTUAL_STELEMREF:
+ label = "virt_stelem";
+ break;
+ case WRAPPER_SUBTYPE_FAST_MONITOR_ENTER:
+ label = "fast_mon_enter";
+ break;
+ case WRAPPER_SUBTYPE_FAST_MONITOR_ENTER_V4:
+ label = "fast_mon_enter_4";
+ break;
+ case WRAPPER_SUBTYPE_FAST_MONITOR_EXIT:
+ label = "fast_monitor_exit";
+ break;
+ case WRAPPER_SUBTYPE_PTR_TO_STRUCTURE:
+ label = "ptr2struct";
+ break;
+ case WRAPPER_SUBTYPE_STRUCTURE_TO_PTR:
+ label = "struct2ptr";
+ break;
+ case WRAPPER_SUBTYPE_CASTCLASS_WITH_CACHE:
+ label = "castclass_w_cache";
+ break;
+ case WRAPPER_SUBTYPE_ISINST_WITH_CACHE:
+ label = "isinst_w_cache";
+ break;
+ case WRAPPER_SUBTYPE_RUNTIME_INVOKE_NORMAL:
+ label = "run_inv_norm";
+ break;
+ case WRAPPER_SUBTYPE_RUNTIME_INVOKE_DYNAMIC:
+ label = "run_inv_dyn";
+ break;
+ case WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT:
+ label = "run_inv_dir";
+ break;
+ case WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL:
+ label = "run_inv_vir";
+ break;
+ case WRAPPER_SUBTYPE_ICALL_WRAPPER:
+ label = "icall";
+ break;
+ case WRAPPER_SUBTYPE_NATIVE_FUNC_AOT:
+ label = "native_func_aot";
+ break;
+ case WRAPPER_SUBTYPE_PINVOKE:
+ label = "pinvoke";
+ break;
+ case WRAPPER_SUBTYPE_SYNCHRONIZED_INNER:
+ label = "synch_inner";
+ break;
+ case WRAPPER_SUBTYPE_GSHAREDVT_IN:
+ label = "gshared_in";
+ break;
+ case WRAPPER_SUBTYPE_GSHAREDVT_OUT:
+ label = "gshared_out";
+ break;
+ case WRAPPER_SUBTYPE_ARRAY_ACCESSOR:
+ label = "array_acc";
+ break;
+ case WRAPPER_SUBTYPE_GENERIC_ARRAY_HELPER:
+ label = "generic_arry_help";
+ break;
+ case WRAPPER_SUBTYPE_DELEGATE_INVOKE_VIRTUAL:
+ label = "del_inv_virt";
+ break;
+ case WRAPPER_SUBTYPE_DELEGATE_INVOKE_BOUND:
+ label = "del_inv_bound";
+ break;
case WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG:
- g_string_append_printf (s, "gsharedvt_in_");
+ label = "gsharedvt_in_sig";
break;
case WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG:
- g_string_append_printf (s, "gsharedvt_out_");
+ label = "gsharedvt_out_sig";
break;
default:
g_assert_not_reached ();
+ }
+
+ g_string_append_printf (s, "%s_", label);
+}
+
+static char *
+sanitize_mangled_string (const char *input)
+{
+ GString *s = g_string_new ("");
+
+ for (int i=0; input [i] != '\0'; i++) {
+ char c = input [i];
+ switch (c) {
+ case '.':
+ g_string_append (s, "_dot_");
+ break;
+ case ' ':
+ g_string_append (s, "_");
+ break;
+ case '`':
+ g_string_append (s, "_bt_");
+ break;
+ case '<':
+ g_string_append (s, "_le_");
+ break;
+ case '>':
+ g_string_append (s, "_gt_");
+ break;
+ case '/':
+ g_string_append (s, "_sl_");
+ break;
+ case '[':
+ g_string_append (s, "_lbrack_");
+ break;
+ case ']':
+ g_string_append (s, "_rbrack_");
+ break;
+ case '(':
+ g_string_append (s, "_lparen_");
+ break;
+ case '-':
+ g_string_append (s, "_dash_");
+ break;
+ case ')':
+ g_string_append (s, "_rparen_");
+ break;
+ case ',':
+ g_string_append (s, "_comma_");
+ break;
+ default:
+ g_string_append_c (s, c);
+ }
+ }
+
+ return g_string_free (s, FALSE);
+}
+
+static gboolean
+append_mangled_klass (GString *s, MonoClass *klass)
+{
+ char *klass_desc = mono_class_full_name (klass);
+ g_string_append_printf (s, "_%s_%s_", klass->name_space, klass_desc);
+ g_free (klass_desc);
+
+ // Success
+ return TRUE;
+}
+
+static gboolean
+append_mangled_method (GString *s, MonoMethod *method);
+
+static gboolean
+append_mangled_wrapper (GString *s, MonoMethod *method)
+{
+ gboolean success = TRUE;
+ WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+ g_string_append_printf (s, "wrapper_");
+
+ append_mangled_wrapper_type (s, method->wrapper_type);
+
+ switch (method->wrapper_type) {
+ case MONO_WRAPPER_REMOTING_INVOKE:
+ case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK:
+ case MONO_WRAPPER_XDOMAIN_INVOKE: {
+ MonoMethod *m = mono_marshal_method_from_wrapper (method);
+ g_assert (m);
+ success = success && append_mangled_method (s, m);
+ break;
+ }
+ case MONO_WRAPPER_PROXY_ISINST:
+ case MONO_WRAPPER_LDFLD:
+ case MONO_WRAPPER_LDFLDA:
+ case MONO_WRAPPER_STFLD: {
+ g_assert (info);
+ success = success && append_mangled_klass (s, info->d.proxy.klass);
+ break;
+ }
+ case MONO_WRAPPER_ALLOC: {
+ /* The GC name is saved once in MonoAotFileInfo */
+ g_assert (info->d.alloc.alloc_type != -1);
+ g_string_append_printf (s, "%d_", info->d.alloc.alloc_type);
+ // SlowAlloc, etc
+ g_string_append_printf (s, "%s_", method->name);
+ break;
+ }
+ case MONO_WRAPPER_WRITE_BARRIER: {
+ break;
+ }
+ case MONO_WRAPPER_STELEMREF: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ if (info->subtype == WRAPPER_SUBTYPE_VIRTUAL_STELEMREF)
+ g_string_append_printf (s, "%d", info->d.virtual_stelemref.kind);
+ break;
+ }
+ case MONO_WRAPPER_UNKNOWN: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ if (info->subtype == WRAPPER_SUBTYPE_PTR_TO_STRUCTURE ||
+ info->subtype == WRAPPER_SUBTYPE_STRUCTURE_TO_PTR)
+ success = success && append_mangled_klass (s, method->klass);
+ else if (info->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER)
+ success = success && append_mangled_method (s, info->d.synchronized_inner.method);
+ else if (info->subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR)
+ success = success && append_mangled_method (s, info->d.array_accessor.method);
+ else if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG)
+ append_mangled_signature (s, info->d.gsharedvt.sig);
+ else if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG)
+ append_mangled_signature (s, info->d.gsharedvt.sig);
+ break;
+ }
+ case MONO_WRAPPER_MANAGED_TO_NATIVE: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ if (info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER) {
+ g_string_append_printf (s, "%s", method->name);
+ } else if (info->subtype == WRAPPER_SUBTYPE_NATIVE_FUNC_AOT) {
+ success = success && append_mangled_method (s, info->d.managed_to_native.method);
+ } else {
+ g_assert (info->subtype == WRAPPER_SUBTYPE_NONE || info->subtype == WRAPPER_SUBTYPE_PINVOKE);
+ success = success && append_mangled_method (s, info->d.managed_to_native.method);
+ }
+ break;
+ }
+ case MONO_WRAPPER_SYNCHRONIZED: {
+ MonoMethod *m;
+
+ m = mono_marshal_method_from_wrapper (method);
+ g_assert (m);
+ g_assert (m != method);
+ success = success && append_mangled_method (s, m);
+ break;
+ }
+ case MONO_WRAPPER_MANAGED_TO_MANAGED: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+
+ if (info->subtype == WRAPPER_SUBTYPE_ELEMENT_ADDR) {
+ g_string_append_printf (s, "%d_", info->d.element_addr.rank);
+ g_string_append_printf (s, "%d_", info->d.element_addr.elem_size);
+ } else if (info->subtype == WRAPPER_SUBTYPE_STRING_CTOR) {
+ success = success && append_mangled_method (s, info->d.string_ctor.method);
+ } else {
+ g_assert_not_reached ();
+ }
+ break;
+ }
+ case MONO_WRAPPER_CASTCLASS: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ break;
+ }
+ case MONO_WRAPPER_RUNTIME_INVOKE: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ if (info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT || info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL)
+ success = success && append_mangled_method (s, info->d.runtime_invoke.method);
+ else if (info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_NORMAL)
+ success = success && append_mangled_signature (s, info->d.runtime_invoke.sig);
+ break;
+ }
+ case MONO_WRAPPER_DELEGATE_INVOKE:
+ case MONO_WRAPPER_DELEGATE_BEGIN_INVOKE:
+ case MONO_WRAPPER_DELEGATE_END_INVOKE: {
+ if (method->is_inflated) {
+ /* These wrappers are identified by their class */
+ g_string_append_printf (s, "i_");
+ success = success && append_mangled_klass (s, method->klass);
+ } else {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+
+ g_string_append_printf (s, "u_");
+ if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE)
+ append_mangled_wrapper_subtype (s, info->subtype);
+ g_string_append_printf (s, "u_sigstart");
+ }
break;
}
+ case MONO_WRAPPER_NATIVE_TO_MANAGED: {
+ g_assert (info);
+ success = success && append_mangled_method (s, info->d.native_to_managed.method);
+ success = success && append_mangled_klass (s, method->klass);
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ }
+ return success && append_mangled_signature (s, mono_method_signature (method));
+}
+
+static void
+append_mangled_context (GString *str, MonoGenericContext *context)
+{
+ GString *res = g_string_new ("");
+
+ g_string_append_printf (res, "gens_");
+ g_string_append (res, "00");
+
+ gboolean good = context->class_inst && context->class_inst->type_argc > 0;
+ good = good || (context->method_inst && context->method_inst->type_argc > 0);
+ g_assert (good);
+
+ if (context->class_inst)
+ mono_ginst_get_desc (res, context->class_inst);
+ if (context->method_inst) {
+ if (context->class_inst)
+ g_string_append (res, "11");
+ mono_ginst_get_desc (res, context->method_inst);
+ }
+ g_string_append_printf (str, "gens_%s", res->str);
+}
+
+static gboolean
+append_mangled_method (GString *s, MonoMethod *method)
+{
+ if (method->wrapper_type)
+ return append_mangled_wrapper (s, method);
- supported = append_mangled_signature (s, info->d.gsharedvt.sig);
- if (!supported) {
+ g_string_append_printf (s, "%s_", method->klass->image->assembly->aname.name);
+
+ if (method->is_inflated) {
+ g_string_append_printf (s, "inflated_");
+ MonoMethodInflated *imethod = (MonoMethodInflated*) method;
+ g_assert (imethod->context.class_inst != NULL || imethod->context.method_inst != NULL);
+
+ append_mangled_context (s, &imethod->context);
+ g_string_append_printf (s, "_declared_by_");
+ append_mangled_method (s, imethod->declaring);
+ } else if (method->is_generic) {
+ g_string_append_printf (s, "generic_");
+ append_mangled_klass (s, method->klass);
+ g_string_append_printf (s, "_%s_", method->name);
+
+ MonoGenericContainer *container = mono_method_get_generic_container (method);
+ g_string_append_printf (s, "_%s");
+ append_mangled_context (s, &container->context);
+
+ return append_mangled_signature (s, mono_method_signature (method));
+ } else {
+ g_string_append_printf (s, "_");
+ append_mangled_klass (s, method->klass);
+ g_string_append_printf (s, "_%s_", method->name);
+ if (!append_mangled_signature (s, mono_method_signature (method))) {
+ g_string_free (s, TRUE);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/*
+ * mono_aot_get_mangled_method_name:
+ *
+ * Return a unique mangled name for METHOD, or NULL.
+ */
+char*
+mono_aot_get_mangled_method_name (MonoMethod *method)
+{
+ GString *s = g_string_new ("aot_");
+ if (!append_mangled_method (s, method)) {
g_string_free (s, TRUE);
return NULL;
+ } else {
+ char *out = g_string_free (s, FALSE);
+ // Scrub method and class names
+ char *cleaned = sanitize_mangled_string (out);
+ g_free (out);
+ return cleaned;
}
-
- return g_string_free (s, FALSE);
}
gboolean
{
int status = 0;
-#if HOST_WIN32
+#if defined(HOST_WIN32) && defined(HAVE_SYSTEM)
// We need an extra set of quotes around the whole command to properly handle commands
// with spaces since internally the command is called through "cmd /c.
char * quoted_command = g_strdup_printf ("\"%s\"", command);
methods [i] = (MonoMethod *)g_ptr_array_index (acfg->methods, i);
i = 0;
while (i < methods_len) {
+ MonoError error;
+ MonoInternalThread *thread;
+
frag = g_ptr_array_new ();
for (j = 0; j < len; ++j) {
if (i < methods_len) {
}
user_data = g_new0 (gpointer, 3);
- user_data [0] = mono_domain_get ();
- user_data [1] = acfg;
- user_data [2] = frag;
+ user_data [0] = acfg;
+ user_data [1] = frag;
- thread_handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, NULL, NULL);
+ thread = mono_thread_create_internal (mono_domain_get (), compile_thread_main, (gpointer) user_data, MONO_THREAD_CREATE_FLAGS_NONE, &error);
+ mono_error_assert_ok (&error);
+
+ thread_handle = mono_threads_open_thread_handle (thread->handle);
g_ptr_array_add (threads, thread_handle);
}
g_free (methods);
}
}
+ fclose (infile);
acfg->profile_data = g_list_append (acfg->profile_data, data);
}
}
}
- if (mono_aot_mode_is_full (&acfg->aot_opts))
+ if (mono_aot_mode_is_full (&acfg->aot_opts)) {
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_FULL_AOT);
+ acfg->is_full_aot = TRUE;
+ }
if (mono_threads_is_coop_enabled ())
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS);