#include <mono/utils/mono-threads.h>
#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/checked-build.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
#include <mono/io-layer/io-layer.h>
#include "mini.h"
void *ptr;
if (mono_aot_only)
- g_error ("Attempting to allocate from the global code manager while running with --aot-only.\n");
+ g_error ("Attempting to allocate from the global code manager while running in aot-only mode.\n");
if (!global_codeman) {
/* This can happen during startup */
return ji;
}
+#if !defined(DISABLE_LOGGING) && !defined(DISABLE_JIT)
+
+static const char* const patch_info_str[] = {
+#define PATCH_INFO(a,b) "" #a,
+#include "patch-info.h"
+#undef PATCH_INFO
+};
+
+const char*
+mono_ji_type_to_string (MonoJumpInfoType type)
+{
+ return patch_info_str [type];
+}
+
+void
+mono_print_ji (const MonoJumpInfo *ji)
+{
+ switch (ji->type) {
+ case MONO_PATCH_INFO_RGCTX_FETCH: {
+ MonoJumpInfoRgctxEntry *entry = ji->data.rgctx_entry;
+
+ printf ("[RGCTX_FETCH ");
+ mono_print_ji (entry->data);
+ printf (" - %s]", mono_rgctx_info_type_to_str (entry->info_type));
+ break;
+ }
+ case MONO_PATCH_INFO_METHODCONST: {
+ char *s = mono_method_full_name (ji->data.method, TRUE);
+ printf ("[METHODCONST - %s]", s);
+ g_free (s);
+ break;
+ }
+ case MONO_PATCH_INFO_INTERNAL_METHOD: {
+ printf ("[INTERNAL_METHOD - %s]", ji->data.name);
+ break;
+ }
+ default:
+ printf ("[%s]", patch_info_str [ji->type]);
+ break;
+ }
+}
+
+#else
+
+const char*
+mono_ji_type_to_string (MonoJumpInfoType type)
+{
+ return "";
+}
+
+void
+mono_print_ji (const MonoJumpInfo *ji)
+{
+}
+
+#endif
+
/**
* mono_patch_info_dup_mp:
*
case MONO_PATCH_INFO_GOT_OFFSET:
case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
case MONO_PATCH_INFO_AOT_MODULE:
+ case MONO_PATCH_INFO_GET_TLS_TRAMP:
return (ji->type << 8);
case MONO_PATCH_INFO_CASTCLASS_CACHE:
return (ji->type << 8) | (ji->data.index);
break;
case MONO_PATCH_INFO_IID:
mono_class_init (patch_info->data.klass);
- target = GINT_TO_POINTER ((int)patch_info->data.klass->interface_id);
+ target = GUINT_TO_POINTER (patch_info->data.klass->interface_id);
break;
case MONO_PATCH_INFO_ADJUSTED_IID:
mono_class_init (patch_info->data.klass);
- target = GINT_TO_POINTER ((int)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
+ target = GUINT_TO_POINTER ((guint32)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
break;
case MONO_PATCH_INFO_VTABLE:
target = mono_class_vtable (domain, patch_info->data.klass);
}
g_assert (vtable);
- if (!vtable->initialized && !(vtable->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
+ if (!vtable->initialized && !mono_class_is_before_field_init (vtable->klass) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
/* Done by the generated code */
;
else {
case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER:
target = mini_get_gsharedvt_wrapper (TRUE, NULL, patch_info->data.sig, NULL, -1, FALSE);
break;
+ case MONO_PATCH_INFO_GET_TLS_TRAMP:
+#ifdef MONO_ARCH_HAVE_GET_TLS_TRAMP
+ target = mono_arch_get_get_tls_tramp ();
+#else
+ target = NULL;
+#endif
+ break;
default:
g_assert_not_reached ();
}
if ((code = mono_aot_get_method_checked (domain, method, error))) {
MonoVTable *vtable;
+ if (mono_runtime_is_critical_method (method) || mono_gc_is_critical_method (method)) {
+ /*
+ * The suspend code needs to be able to lookup these methods by ip in async context,
+ * so preload their jit info.
+ */
+ MonoJitInfo *ji = mono_jit_info_table_find (domain, code);
+ g_assert (ji);
+ }
+
/*
* In llvm-only mode, method might be a shared method, so we can't initialize its class.
* This is not a problem, since it will be initialized when the method is first
*/
mono_class_setup_vtable (method->klass);
if (mono_class_has_failure (method->klass)) {
- MonoException *fail_exc = mono_class_get_exception_for_failure (method->klass);
+ mono_error_set_for_class_failure (error, method->klass);
if (exc)
- *exc = (MonoObject*)fail_exc;
- mono_error_set_exception_instance (error, fail_exc);
+ *exc = (MonoObject*)mono_class_get_exception_for_failure (method->klass);
return NULL;
}
}
typedef struct {
MonoVTable *vtable;
int slot;
-} IMTThunkInfo;
+} IMTTrampInfo;
-typedef gpointer (*IMTThunkFunc) (gpointer *arg, MonoMethod *imt_method);
+typedef gpointer (*IMTTrampFunc) (gpointer *arg, MonoMethod *imt_method);
/*
- * mini_llvmonly_initial_imt_thunk:
+ * mini_llvmonly_initial_imt_tramp:
*
- * This function is called the first time a call is made through an IMT thunk.
- * It should have the same signature as the mono_llvmonly_imt_thunk_... functions.
+ * This function is called the first time a call is made through an IMT trampoline.
+ * It should have the same signature as the mono_llvmonly_imt_tramp_... functions.
*/
static gpointer
-mini_llvmonly_initial_imt_thunk (gpointer *arg, MonoMethod *imt_method)
+mini_llvmonly_initial_imt_tramp (gpointer *arg, MonoMethod *imt_method)
{
- IMTThunkInfo *info = (IMTThunkInfo*)arg;
+ IMTTrampInfo *info = (IMTTrampInfo*)arg;
gpointer *imt;
gpointer *ftndesc;
- IMTThunkFunc func;
+ IMTTrampFunc func;
mono_vtable_build_imt_slot (info->vtable, info->slot);
imt = (gpointer*)info->vtable;
imt -= MONO_IMT_SIZE;
- /* Return what the real IMT thunk returns */
+ /* Return what the real IMT trampoline returns */
ftndesc = imt [info->slot];
func = ftndesc [0];
- if (func == (IMTThunkFunc)mini_llvmonly_initial_imt_thunk)
+ if (func == (IMTTrampFunc)mini_llvmonly_initial_imt_tramp)
/* Happens when the imt slot contains only a generic virtual method */
return NULL;
return func ((gpointer *)ftndesc [1], imt_method);
/* This is called indirectly through an imt slot. */
static gpointer
-mono_llvmonly_imt_thunk (gpointer *arg, MonoMethod *imt_method)
+mono_llvmonly_imt_tramp (gpointer *arg, MonoMethod *imt_method)
{
int i = 0;
- /* arg points to an array created in mono_llvmonly_get_imt_thunk () */
+ /* arg points to an array created in mono_llvmonly_get_imt_trampoline () */
while (arg [i] && arg [i] != imt_method)
i += 2;
g_assert (arg [i]);
return arg [i + 1];
}
-/* Optimized versions of mono_llvmonly_imt_thunk () for different table sizes */
+/* Optimized versions of mono_llvmonly_imt_trampoline () for different table sizes */
static gpointer
-mono_llvmonly_imt_thunk_1 (gpointer *arg, MonoMethod *imt_method)
+mono_llvmonly_imt_tramp_1 (gpointer *arg, MonoMethod *imt_method)
{
//g_assert (arg [0] == imt_method);
return arg [1];
}
static gpointer
-mono_llvmonly_imt_thunk_2 (gpointer *arg, MonoMethod *imt_method)
+mono_llvmonly_imt_tramp_2 (gpointer *arg, MonoMethod *imt_method)
{
//g_assert (arg [0] == imt_method || arg [2] == imt_method);
if (arg [0] == imt_method)
}
static gpointer
-mono_llvmonly_imt_thunk_3 (gpointer *arg, MonoMethod *imt_method)
+mono_llvmonly_imt_tramp_3 (gpointer *arg, MonoMethod *imt_method)
{
//g_assert (arg [0] == imt_method || arg [2] == imt_method || arg [4] == imt_method);
if (arg [0] == imt_method)
}
/*
- * A version of the imt thunk used for generic virtual/variant iface methods.
- * Unlikely a normal imt thunk, its possible that IMT_METHOD is not found
+ * A version of the imt trampoline used for generic virtual/variant iface methods.
+ * Unlikely a normal imt trampoline, its possible that IMT_METHOD is not found
* in the search table. The original JIT code had a 'fallback' trampoline it could
* call, but we can't do that, so we just return NULL, and the compiled code
* will handle it.
*/
static gpointer
-mono_llvmonly_fallback_imt_thunk (gpointer *arg, MonoMethod *imt_method)
+mono_llvmonly_fallback_imt_tramp (gpointer *arg, MonoMethod *imt_method)
{
int i = 0;
}
static gpointer
-mono_llvmonly_get_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp)
+mono_llvmonly_get_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp)
{
gpointer *buf;
gpointer *res;
gboolean virtual_generic = FALSE;
/*
- * Create an array which is passed to the imt thunk functions.
+ * Create an array which is passed to the imt trampoline functions.
* The array contains MonoMethod-function descriptor pairs, terminated by a NULL entry.
*/
res = (void **)mono_domain_alloc (domain, 2 * sizeof (gpointer));
switch (real_count) {
case 1:
- res [0] = mono_llvmonly_imt_thunk_1;
+ res [0] = mono_llvmonly_imt_tramp_1;
break;
case 2:
- res [0] = mono_llvmonly_imt_thunk_2;
+ res [0] = mono_llvmonly_imt_tramp_2;
break;
case 3:
- res [0] = mono_llvmonly_imt_thunk_3;
+ res [0] = mono_llvmonly_imt_tramp_3;
break;
default:
- res [0] = mono_llvmonly_imt_thunk;
+ res [0] = mono_llvmonly_imt_tramp;
break;
}
if (virtual_generic || fail_tramp)
- res [0] = mono_llvmonly_fallback_imt_thunk;
+ res [0] = mono_llvmonly_fallback_imt_tramp;
res [1] = buf;
return res;
if (mono_llvm_only) {
if (slot_index < 0) {
- /* Initialize the IMT thunks to a 'trampoline' so the generated code doesn't have to initialize it */
+ /* Initialize the IMT trampoline to a 'trampoline' so the generated code doesn't have to initialize it */
// FIXME: Memory management
gpointer *ftndesc = g_malloc (2 * sizeof (gpointer));
- IMTThunkInfo *info = g_new0 (IMTThunkInfo, 1);
+ IMTTrampInfo *info = g_new0 (IMTTrampInfo, 1);
info->vtable = vt;
info->slot = index;
- ftndesc [0] = mini_llvmonly_initial_imt_thunk;
+ ftndesc [0] = mini_llvmonly_initial_imt_tramp;
ftndesc [1] = info;
mono_memory_barrier ();
return ftndesc;
return NULL;
is_virtual_generic = method->is_inflated && mono_method_get_declaring_generic_method (method)->is_generic;
- is_interface = method->klass->flags & TYPE_ATTRIBUTE_INTERFACE ? TRUE : FALSE;
+ is_interface = mono_class_is_interface (method->klass);
load_imt_reg = is_virtual_generic || is_interface;
if (is_interface)
}
if (mono_llvm_only) {
- mono_install_imt_thunk_builder (mono_llvmonly_get_imt_thunk);
- mono_set_always_build_imt_thunks (TRUE);
+ mono_install_imt_trampoline_builder (mono_llvmonly_get_imt_trampoline);
+ mono_set_always_build_imt_trampolines (TRUE);
} else if (mono_aot_only) {
- mono_install_imt_thunk_builder (mono_aot_get_imt_thunk);
+ mono_install_imt_trampoline_builder (mono_aot_get_imt_trampoline);
} else {
- mono_install_imt_thunk_builder (mono_arch_build_imt_thunk);
+ mono_install_imt_trampoline_builder (mono_arch_build_imt_trampoline);
}
/*Init arch tls information only after the metadata side is inited to make sure we see dynamic appdomain tls keys*/
*/
mono_runtime_set_no_exec (TRUE);
+ mono_mem_account_register_counters ();
+
#define JIT_RUNTIME_WORKS
#ifdef JIT_RUNTIME_WORKS
mono_install_runtime_cleanup ((MonoDomainFunc)mini_cleanup);
ves_icall_get_trace);
mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers",
mono_runtime_install_handlers);
+ mono_add_internal_call ("Mono.Runtime::mono_runtime_cleanup_handlers",
+ mono_runtime_cleanup_handlers);
#if defined(PLATFORM_ANDROID) || defined(TARGET_ANDROID)
mono_add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal",
g_print ("IMT colliding slots: %ld\n", mono_stats.imt_slots_with_collisions);
g_print ("IMT max collisions: %ld\n", mono_stats.imt_max_collisions_in_slot);
g_print ("IMT methods at max col: %ld\n", mono_stats.imt_method_count_when_max_collisions);
- g_print ("IMT thunks size: %ld\n", mono_stats.imt_thunks_size);
+ g_print ("IMT trampolines size: %ld\n", mono_stats.imt_trampolines_size);
g_print ("JIT info table inserts: %ld\n", mono_stats.jit_info_table_insert_count);
g_print ("JIT info table removes: %ld\n", mono_stats.jit_info_table_remove_count);
}
if (method->flags & METHOD_ATTRIBUTE_ABSTRACT)
continue;
- if (method->is_generic || method->klass->generic_container)
+ if (method->is_generic || mono_class_is_gtd (method->klass))
continue;
count++;
/* Not used */
g_assert_not_reached ();
}
+
+// Custom handlers currently only implemented by Windows.
+#ifndef HOST_WIN32
+gboolean
+mono_runtime_install_custom_handlers (const char *handlers)
+{
+ return FALSE;
+}
+
+void
+mono_runtime_install_custom_handlers_usage (void)
+{
+ fprintf (stdout,
+ "Custom Handlers:\n"
+ " --handlers=HANDLERS Enable handler support, HANDLERS is a comma\n"
+ " separated list of available handlers to install.\n"
+ "\n"
+ "No handlers supported on current platform.\n");
+}
+#endif /* HOST_WIN32 */