get_method_from_ip (void *ip)
{
MonoJitInfo *ji;
- char *method;
+ MonoMethod *method;
+ char *method_name;
char *res;
MonoDomain *domain = mono_domain_get ();
MonoDebugSourceLocation *location;
return res;
}
- method = mono_method_full_name (jinfo_get_method (ji), TRUE);
+ method = jinfo_get_method (ji);
+ method_name = mono_method_full_name (method, TRUE);
/* FIXME: unused ? */
- location = mono_debug_lookup_source_location (jinfo_get_method (ji), (guint32)((guint8*)ip - (guint8*)ji->code_start), domain);
+ location = mono_debug_lookup_source_location (method, (guint32)((guint8*)ip - (guint8*)ji->code_start), domain);
- res = g_strdup_printf (" %s + 0x%x (%p %p) [%p - %s]", method, (int)((char*)ip - (char*)ji->code_start), ji->code_start, (char*)ji->code_start + ji->code_size, domain, domain->friendly_name);
+ res = g_strdup_printf (" %s {%p} + 0x%x (%p %p) [%p - %s]", method_name, method, (int)((char*)ip - (char*)ji->code_start), ji->code_start, (char*)ji->code_start + ji->code_size, domain, domain->friendly_name);
mono_debug_free_source_location (location);
- g_free (method);
+ g_free (method_name);
return res;
}
gconstpointer
mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile)
{
+ MonoError error;
char *name;
MonoMethod *wrapper;
gconstpointer trampoline;
g_free (name);
if (do_compile) {
- trampoline = mono_compile_method (wrapper);
+ trampoline = mono_compile_method_checked (wrapper, &error);
+ mono_error_assert_ok (&error);
} else {
- MonoError error;
trampoline = mono_create_jit_trampoline (domain, wrapper, &error);
mono_error_assert_ok (&error);
*
* In coop mode:
* - @dummy: contains the original domain
- * - @return: a cookie containing current MonoThreadInfo* if it was in BLOCKING mode, NULL otherwise
+ * - @return: a cookie containing current MonoThreadInfo*.
*/
gpointer
mono_jit_thread_attach (MonoDomain *domain, gpointer *dummy)
g_assert (domain);
- if (!mono_threads_is_coop_enabled ()) {
+ /* On coop, when we detached, we moved the thread from RUNNING->BLOCKING. If we try to
+ * reattach we do a BLOCKING->RUNNING transition. If the thread is fresh,
+ * mono_thread_attach() will do a STARTING->RUNNING transition so we're only responsible
+ * for making the cookie. */
+ gboolean fresh_thread = FALSE;
+ {
+ MonoThreadInfo *info;
+
+ info = mono_thread_info_current_unchecked ();
+ fresh_thread = !info || !mono_thread_info_is_live (info);
+ }
+ {
gboolean attached;
#ifdef MONO_HAVE_FAST_TLS
if (orig != domain)
mono_domain_set (domain, TRUE);
+ }
+ if (!mono_threads_is_coop_enabled ()) {
return orig != domain ? orig : NULL;
} else {
- MonoThreadInfo *info;
-
- info = mono_thread_info_current_unchecked ();
- if (!info || !mono_thread_info_is_live (info)) {
- /* thread state STARTING -> RUNNING */
- mono_thread_attach (domain);
-
- // #678164
- mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background);
-
+ if (fresh_thread) {
*dummy = NULL;
-
- /* mono_threads_reset_blocking_start returns the current MonoThreadInfo
- * if we were in BLOCKING mode */
- return mono_thread_info_current ();
+ /* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
+ * return the right cookie. */
+ return mono_threads_enter_gc_unsafe_region_cookie (mono_thread_info_current ());
} else {
- orig = mono_domain_get ();
-
- /* orig might be null if we did an attach -> detach -> attach sequence */
-
- if (orig != domain)
- mono_domain_set (domain, TRUE);
-
*dummy = orig;
-
/* thread state (BLOCKING|RUNNING) -> RUNNING */
- return mono_threads_reset_blocking_start (dummy);
+ return mono_threads_enter_gc_unsafe_region (dummy);
}
}
}
/* it won't do anything if cookie is NULL
* thread state RUNNING -> (RUNNING|BLOCKING) */
- mono_threads_reset_blocking_end (cookie, dummy);
+ mono_threads_exit_gc_unsafe_region (cookie, dummy);
if (orig != domain) {
if (!orig)
thread = mono_thread_info_current_unchecked ();
if (thread)
thread->jit_data = jit_tls;
- if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL)
- mono_runtime_setup_stat_profiler ();
mono_arch_cpu_init ();
}
#endif
break;
case MONO_PATCH_INFO_METHOD:
-#if defined(__native_client_codegen__) && defined(USE_JUMP_TABLES)
- /*
- * If we use jumptables, for recursive calls we cannot
- * avoid trampoline, as we not yet know where we will
- * be installed.
- */
- target = mono_create_jit_trampoline (domain, patch_info->data.method, error);
- if (!mono_error_ok (error))
- return NULL;
-#else
if (patch_info->data.method == method) {
target = code;
} else {
if (!mono_error_ok (error))
return NULL;
}
-#endif
break;
case MONO_PATCH_INFO_METHOD_CODE_SLOT: {
gpointer code_slot;
mono_class_init (method->klass);
- if ((code = mono_aot_get_method (domain, method))) {
+ if ((code = mono_aot_get_method_checked (domain, method, error))) {
MonoVTable *vtable;
/*
return NULL;
}
}
+ if (!is_ok (error))
+ return NULL;
}
#endif
static gpointer
mono_jit_create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target)
{
+ MonoError error;
MonoMethod *nm;
guint8 *addr = NULL;
if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
(mono_method_signature (method)->hasthis && (mono_class_is_marshalbyref (method->klass) || method->klass == mono_defaults.object_class))) {
nm = mono_marshal_get_remoting_invoke_for_target (method, target);
- addr = (guint8 *)mono_compile_method (nm);
+ addr = (guint8 *)mono_compile_method_checked (nm, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
} else
{
- addr = (guint8 *)mono_compile_method (method);
+ addr = (guint8 *)mono_compile_method_checked (method, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
return mono_get_addr_from_ftnptr (addr);
}
mono_counters_register ("Methods from AOT", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.methods_aot);
mono_counters_register ("Methods JITted using mono JIT", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.methods_without_llvm);
mono_counters_register ("Methods JITted using LLVM", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.methods_with_llvm);
- mono_counters_register ("JIT/method-to-IR (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_method_to_ir);
+ mono_counters_register ("JIT/method_to_ir (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_method_to_ir);
mono_counters_register ("JIT/liveness_handle_exception_clauses (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_liveness_handle_exception_clauses);
mono_counters_register ("JIT/handle_out_of_line_bblock (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_handle_out_of_line_bblock);
mono_counters_register ("JIT/decompose_long_opts (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_decompose_long_opts);
mono_thread_attach (domain);
#endif
+ if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL)
+ mono_runtime_setup_stat_profiler ();
+
mono_profiler_runtime_initialized ();
MONO_VES_INIT_END ();
register_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", "object", FALSE);
register_icall (mono_thread_force_interruption_checkpoint_noraise, "mono_thread_force_interruption_checkpoint_noraise", "object", FALSE);
#ifndef DISABLE_REMOTING
- register_icall (mono_load_remote_field_new, "mono_load_remote_field_new", "object object ptr ptr", FALSE);
- register_icall (mono_store_remote_field_new, "mono_store_remote_field_new", "void object ptr ptr object", FALSE);
+ register_icall (mono_load_remote_field_new_icall, "mono_load_remote_field_new_icall", "object object ptr ptr", FALSE);
+ register_icall (mono_store_remote_field_new_icall, "mono_store_remote_field_new_icall", "void object ptr ptr object", FALSE);
#endif
#if defined(__native_client__) || defined(__native_client_codegen__)
register_icall (mono_helper_stelem_ref_check, "mono_helper_stelem_ref_check", "void object object", FALSE);
register_icall (ves_icall_object_new, "ves_icall_object_new", "object ptr ptr", FALSE);
register_icall (ves_icall_object_new_specific, "ves_icall_object_new_specific", "object ptr", FALSE);
- register_icall (mono_array_new, "mono_array_new", "object ptr ptr int32", FALSE);
+ register_icall (ves_icall_array_new, "ves_icall_array_new", "object ptr ptr int32", FALSE);
register_icall (ves_icall_array_new_specific, "ves_icall_array_new_specific", "object ptr int32", FALSE);
register_icall (ves_icall_runtime_class_init, "ves_icall_runtime_class_init", "void ptr", FALSE);
register_icall (mono_ldftn, "mono_ldftn", "ptr ptr", FALSE);
/* This accesses metadata so needs to be called before runtime shutdown */
print_jit_stats ();
- mono_profiler_shutdown ();
-
#ifndef MONO_CROSS_COMPILE
mono_runtime_cleanup (domain);
#endif
+ mono_profiler_shutdown ();
+
free_jit_tls_data ((MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id));
mono_icall_cleanup ();
mono_os_mutex_destroy (&jit_mutex);
mono_code_manager_cleanup ();
-
-#ifdef USE_JUMP_TABLES
- mono_jumptable_cleanup ();
-#endif
}
void
g_print ("Compiling %d %s\n", count, desc);
g_free (desc);
}
- mono_compile_method (method);
+ mono_compile_method_checked (method, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ continue;
+ }
if (strcmp (method->name, "Finalize") == 0) {
invoke = mono_marshal_get_runtime_invoke (method, FALSE);
- mono_compile_method (invoke);
+ mono_compile_method_checked (invoke, &error);
+ mono_error_assert_ok (&error);
}
#ifndef DISABLE_REMOTING
if (mono_class_is_marshalbyref (method->klass) && mono_method_signature (method)->hasthis) {
invoke = mono_marshal_get_remoting_invoke_with_check (method);
- mono_compile_method (invoke);
+ mono_compile_method_checked (invoke, &error);
+ mono_error_assert_ok (&error);
}
#endif
}
/* Not used */
g_assert_not_reached ();
}
-
-#ifdef USE_JUMP_TABLES
-#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
-
-typedef struct MonoJumpTableChunk {
- guint32 total;
- guint32 active;
- struct MonoJumpTableChunk *previous;
- /* gpointer entries[total]; */
-} MonoJumpTableChunk;
-
-static MonoJumpTableChunk* g_jumptable;
-#define mono_jumptable_lock() mono_os_mutex_lock (&jumptable_mutex)
-#define mono_jumptable_unlock() mono_os_mutex_unlock (&jumptable_mutex)
-static mono_mutex_t jumptable_mutex;
-
-static MonoJumpTableChunk*
-mono_create_jumptable_chunk (guint32 max_entries)
-{
- guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
- MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
- chunk->total = max_entries;
- return chunk;
-}
-
-void
-mono_jumptable_init (void)
-{
- if (g_jumptable == NULL) {
- mono_os_mutex_init_recursive (&jumptable_mutex);
- g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
- }
-}
-
-gpointer*
-mono_jumptable_add_entry (void)
-{
- return mono_jumptable_add_entries (1);
-}
-
-gpointer*
-mono_jumptable_add_entries (guint32 entries)
-{
- guint32 index;
- gpointer *result;
-
- mono_jumptable_init ();
- mono_jumptable_lock ();
- index = g_jumptable->active;
- if (index + entries >= g_jumptable->total) {
- /*
- * Grow jumptable, by adding one more chunk.
- * We cannot realloc jumptable, as there could be pointers
- * to existing jump table entries in the code, so instead
- * we just add one more chunk.
- */
- guint32 max_entries = entries;
- MonoJumpTableChunk *new_chunk;
-
- if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
- max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
- new_chunk = mono_create_jumptable_chunk (max_entries);
- /* Link old jumptable, so that we could free it up later. */
- new_chunk->previous = g_jumptable;
- g_jumptable = new_chunk;
- index = 0;
- }
- g_jumptable->active = index + entries;
- result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
- mono_jumptable_unlock();
-
- return result;
-}
-
-void
-mono_jumptable_cleanup (void)
-{
- if (g_jumptable) {
- MonoJumpTableChunk *current = g_jumptable, *prev;
- while (current != NULL) {
- prev = current->previous;
- g_free (current);
- current = prev;
- }
- g_jumptable = NULL;
- mono_os_mutex_destroy (&jumptable_mutex);
- }
-}
-
-gpointer*
-mono_jumptable_get_entry (guint8 *code_ptr)
-{
- return mono_arch_jumptable_entry_from_code (code_ptr);
-}
-#endif