2009-11-20 Zoltan Varga <vargaz@gmail.com>
+ * mini.c mini-trampolines.c driver.c: Add a 'mono_use_llvm' flag to control
+ whenever the runtime uses LLVM code. Add a '--llvm' command line option to set
+ it. Use this flag to control llvm related code paths instead of #ifdef
+ ENABLE_LLVM, so a runtime configured without --enable-llvm can use LLVM compiled
+ AOT code.
+
+ * aot-runtime.c aot-compiler.c: Add a 'flag' field to MonoAotFileInfo.
+
+ * mini.h: Bump AOT file format version.
+
* tramp-ppc.c (mono_arch_create_generic_class_init_trampoline_full): These
receive their argument in MONO_ARCH_VTABLE_REG, not in the first argument reg.
const char *temp_prefix;
guint32 label_generator;
gboolean llvm;
+ MonoAotFileFlags flags;
} MonoAotCompile;
#define mono_acfg_lock(acfg) EnterCriticalSection (&((acfg)->mutex))
emit_int32 (acfg, (int)(acfg->got_offset * sizeof (gpointer)));
emit_int32 (acfg, acfg->plt_offset);
emit_int32 (acfg, acfg->nmethods);
+ emit_int32 (acfg, acfg->flags);
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
emit_int32 (acfg, acfg->num_trampolines [i]);
#ifdef ENABLE_LLVM
acfg->llvm = TRUE;
acfg->aot_opts.asm_writer = TRUE;
+ acfg->flags |= MONO_AOT_FILE_FLAG_WITH_LLVM;
#endif
load_profile_files (acfg);
}
g_free (build_info);
+ find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&file_info);
+ g_assert (file_info);
+
{
char *full_aot_str;
usable = FALSE;
}
+ if ((((MonoAotFileInfo*)file_info)->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module %s is compiled with LLVM.\n", aot_name);
+ usable = FALSE;
+ }
+
if (!usable) {
if (mono_aot_only) {
fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode.\n", aot_name);
return;
}
- find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&file_info);
- g_assert (file_info);
-
amodule = g_new0 (MonoAotModule, 1);
amodule->aot_name = aot_name;
amodule->assembly = assembly;
" mode is one of cas, core-clr, verifiable or validil\n"
" --attach=OPTIONS Pass OPTIONS to the attach agent in the runtime.\n"
" Currently the only supported option is 'disable'.\n"
+ " --llvm Controls whenever the runtime uses LLVM compiled code.\n"
);
}
#ifdef MONO_JIT_INFO_TABLE_TEST
} else if (strcmp (argv [i], "--test-jit-info-table") == 0) {
test_jit_info_table = TRUE;
+#endif
+ } else if (strcmp (argv [i], "--llvm") == 0) {
+#ifndef MONO_ARCH_LLVM_SUPPORTED
+ fprintf (stderr, "--llvm not supported on this platform.\n");
+ return 1;
+#else
+ mono_use_llvm = TRUE;
#endif
} else {
fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
#define MONO_ARCH_DYN_CALL_PARAM_AREA 0
#define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1
+#define MONO_ARCH_LLVM_SUPPORTED 1
#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_metadata_signature_equal ((caller_sig), (callee_sig))
return addr;
}
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
/*
* mono_llvm_vcall_trampoline:
*
return mono_monitor_enter_trampoline;
case MONO_TRAMPOLINE_MONITOR_EXIT:
return mono_monitor_exit_trampoline;
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
case MONO_TRAMPOLINE_LLVM_VCALL:
return mono_llvm_vcall_trampoline;
#endif
mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER);
mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_EXIT] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
mono_trampoline_code [MONO_TRAMPOLINE_LLVM_VCALL] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_LLVM_VCALL);
#endif
}
return code;
}
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
/*
* mono_create_llvm_vcall_trampoline:
*
static int methods_with_llvm, methods_without_llvm;
#endif
+/*
+ * This flag controls whenever the runtime uses LLVM compiled code.
+ * Enabling this causes different/slower code paths to be used, which is why it
+ * defaults to FALSE if ENABLE_LLVM is not defined, i.e. the runtime is only capable of
+ * running AOT code compiled by LLVM.
+ * Changes when this flag is set include:
+ * - a per method vtable trampoline is used to handle virtual calls, instead of only
+ * one trampoline.
+ */
+#ifdef ENABLE_LLVM
+gboolean mono_use_llvm = TRUE;
+#else
+gboolean mono_use_llvm = FALSE;
+#endif
+
#define mono_jit_lock() EnterCriticalSection (&jit_mutex)
#define mono_jit_unlock() LeaveCriticalSection (&jit_mutex)
static CRITICAL_SECTION jit_mutex;
break;
#endif
case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
+ g_assert (mono_use_llvm);
target = mono_create_llvm_imt_trampoline (domain, patch_info->data.imt_tramp->method, patch_info->data.imt_tramp->vt_offset);
#else
g_assert_not_reached ();
#ifdef JIT_TRAMPOLINES_WORK
mono_install_compile_method (mono_jit_compile_method);
mono_install_free_method (mono_jit_free_method);
-#ifdef ENABLE_LLVM
- /* The runtime currently only uses this for filling out vtables */
- mono_install_trampoline (mono_create_llvm_vcall_trampoline);
+#ifdef MONO_ARCH_LLVM_SUPPORTED
+ if (mono_use_llvm)
+ /* The runtime currently only uses this for filling out vtables */
+ mono_install_trampoline (mono_create_llvm_vcall_trampoline);
+ else
+ mono_install_trampoline (mono_create_jit_trampoline);
#else
mono_install_trampoline (mono_create_jit_trampoline);
#endif
mono_install_imt_thunk_builder (mono_aot_get_imt_thunk);
else
mono_install_imt_thunk_builder (mono_arch_build_imt_thunk);
-#ifndef ENABLE_LLVM
- /* LLVM needs a per-method vtable trampoline */
- mono_install_vtable_trampoline (mini_get_vtable_trampoline ());
- /*
- * The imt code in mono_magic_trampoline () can't handle LLVM code. By disabling
- * this, we force iface calls to go through the llvm vcall trampoline.
- */
- mono_install_imt_trampoline (mini_get_imt_trampoline ());
-#endif
+ if (!mono_use_llvm) {
+ /* LLVM needs a per-method vtable trampoline */
+ mono_install_vtable_trampoline (mini_get_vtable_trampoline ());
+ /*
+ * The imt code in mono_magic_trampoline () can't handle LLVM code. By disabling
+ * this, we force iface calls to go through the llvm vcall trampoline.
+ */
+ mono_install_imt_trampoline (mini_get_imt_trampoline ());
+ }
}
#endif
#endif
/* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "60"
+#define MONO_AOT_FILE_VERSION "61"
//TODO: This is x86/amd64 specific.
#define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
MONO_AOT_TRAMP_NUM = 3
} MonoAotTrampoline;
+typedef enum {
+ MONO_AOT_FILE_FLAG_WITH_LLVM = 1
+} MonoAotFileFlags;
+
/* This structure is stored in the AOT file */
typedef struct MonoAotFileInfo
{
guint32 got_size;
guint32 plt_size;
guint32 nmethods;
+ guint32 flags;
guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
extern gboolean mono_do_x86_stack_align;
extern const char *mono_build_date;
extern gboolean mono_do_signal_chaining;
+extern gboolean mono_use_llvm;
#define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 4])
MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
MONO_TRAMPOLINE_MONITOR_ENTER,
MONO_TRAMPOLINE_MONITOR_EXIT,
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
MONO_TRAMPOLINE_LLVM_VCALL,
#endif
MONO_TRAMPOLINE_NUM
MonoJitInfo *ji = NULL;
gboolean can_write;
-#ifdef ENABLE_LLVM
- /* code - 7 might be before the start of the method */
- /* FIXME: Avoid this expensive call somehow */
- ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
-#endif
+ if (mono_use_llvm) {
+ /* code - 7 might be before the start of the method */
+ /* FIXME: Avoid this expensive call somehow */
+ ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
+ }
can_write = mono_breakpoint_clean_code (ji ? ji->code_start : NULL, code, 7, buf, sizeof (buf));