Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections
[mono.git] / mono / mini / mini-runtime.c
index 83420c5224454b776c59d42a65d582694ffa7fcb..f4f30c69e6ba02fb18ddc33d4b0c2e580d4d541b 100644 (file)
@@ -65,6 +65,7 @@
 #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/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -1514,7 +1515,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                handle = mono_ldtoken_checked (patch_info->data.token->image,
                                                           patch_info->data.token->token, &handle_class, patch_info->data.token->has_context ? &patch_info->data.token->context : NULL, error);
                if (!mono_error_ok (error))
-                       g_error ("Could not patch ldtoken due to %s", mono_error_get_message (error));
+                       return NULL;
                mono_class_init (handle_class);
                mono_class_init (mono_class_from_mono_type ((MonoType *)handle));
 
@@ -2355,10 +2356,8 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
        runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
 
        runtime_invoke (NULL, args, exc, info->compiled_method);
-       if (exc && *exc) {
-               mono_error_set_exception_instance (error, (MonoException*) *exc);
+       if (exc && *exc)
                return NULL;
-       }
 
        if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class)
                return mono_value_box_checked (domain, info->ret_box_class, retval, error);
@@ -2544,12 +2543,17 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
        }
 #endif
 
-       if (mono_llvm_only)
-               return mono_llvmonly_runtime_invoke (method, info, obj, params, exc, error);
+       MonoObject *result;
 
-       runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
+       if (mono_llvm_only) {
+               result = mono_llvmonly_runtime_invoke (method, info, obj, params, exc, error);
+               if (!is_ok (error))
+                       return NULL;
+       } else {
+               runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
 
-       MonoObject *result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);
+               result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);
+       }
        if (catchExcInMonoError && *exc != NULL)
                mono_error_set_exception_instance (error, (MonoException*) *exc);
        return result;
@@ -2779,6 +2783,9 @@ MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
        MonoException *exc;
        MONO_SIG_HANDLER_GET_CONTEXT;
 
+       if (mono_runtime_get_no_exec ())
+               exit (1);
+
        MONO_ENTER_GC_UNSAFE_UNBALANCED;
 
        exc = mono_get_exception_execution_engine ("SIGILL");
@@ -3053,6 +3060,17 @@ mini_init_delegate (MonoDelegate *del)
                del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr);
 }
 
+char*
+mono_get_delegate_virtual_invoke_impl_name (gboolean load_imt_reg, int offset)
+{
+       int abs_offset;
+
+       abs_offset = offset;
+       if (abs_offset < 0)
+               abs_offset = - abs_offset;
+       return g_strdup_printf ("delegate_virtual_invoke%s_%s%d", load_imt_reg ? "_imt" : "", offset < 0 ? "m_" : "", abs_offset / SIZEOF_VOID_P);
+}
+
 gpointer
 mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method)
 {
@@ -3104,12 +3122,7 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met
 
        /* FIXME Support more cases */
        if (mono_aot_only) {
-               char tramp_name [256];
-               const char *imt = load_imt_reg ? "_imt" : "";
-               int ind = (load_imt_reg ? (-offset) : offset) / SIZEOF_VOID_P;
-
-               sprintf (tramp_name, "delegate_virtual_invoke%s_%d", imt, ind);
-               cache [idx] = (guint8 *)mono_aot_get_trampoline (tramp_name);
+               cache [idx] = (guint8 *)mono_aot_get_trampoline (mono_get_delegate_virtual_invoke_impl_name (load_imt_reg, offset));
                g_assert (cache [idx]);
        } else {
                cache [idx] = (guint8 *)mono_arch_get_delegate_virtual_invoke_impl (sig, method, offset, load_imt_reg);
@@ -3157,7 +3170,9 @@ mini_parse_debug_option (const char *option)
        else if (!strcmp (option, "gen-seq-points"))
                debug_options.gen_sdb_seq_points = TRUE;
        else if (!strcmp (option, "gen-compact-seq-points"))
-               debug_options.gen_seq_points_compact_data = TRUE;
+               fprintf (stderr, "Mono Warning: option gen-compact-seq-points is deprecated.\n");
+       else if (!strcmp (option, "no-compact-seq-points"))
+               debug_options.no_seq_points_compact_data = TRUE;
        else if (!strcmp (option, "single-imm-size"))
                debug_options.single_imm_size = TRUE;
        else if (!strcmp (option, "init-stacks"))
@@ -3202,7 +3217,7 @@ mini_parse_debug_options (void)
 
                if (!mini_parse_debug_option (arg)) {
                        fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg);
-                       fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'gen-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n");
+                       fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'no-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n");
                        exit (1);
                }
        }
@@ -3317,6 +3332,7 @@ register_jit_stats (void)
        mono_counters_register ("Aliases eliminated", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.alias_removed);
        mono_counters_register ("Aliased loads eliminated", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.loads_eliminated);
        mono_counters_register ("Aliased stores eliminated", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.stores_eliminated);
+       mono_counters_register ("Optimized immediate divisions", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.optimized_divisions);
 }
 
 static void runtime_invoke_info_free (gpointer value);
@@ -3557,6 +3573,10 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_counters_init ();
 
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
+
        mono_threads_runtime_init (&ticallbacks);
 
        if (g_getenv ("MONO_DEBUG") != NULL)
@@ -3684,9 +3704,7 @@ mini_init (const char *filename, const char *runtime_version)
        mono_simd_intrinsics_init ();
 #endif
 
-#if MONO_SUPPORT_TASKLETS
        mono_tasklets_init ();
-#endif
 
        register_trampolines (domain);
 
@@ -3767,9 +3785,6 @@ register_icalls (void)
        register_icall (mono_thread_get_undeniable_exception, "mono_thread_get_undeniable_exception", "object", FALSE);
        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_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_nacl_gc, "mono_nacl_gc", "void", FALSE);
@@ -3968,6 +3983,7 @@ register_icalls (void)
        register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE);
        register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE);
        register_icall (mono_throw_method_access, "mono_throw_method_access", "void ptr ptr", FALSE);
+       register_icall_no_wrapper (mono_dummy_jit_icall, "mono_dummy_jit_icall", "void");
 
        register_icall_with_wrapper (mono_monitor_enter, "mono_monitor_enter", "void obj");
        register_icall_with_wrapper (mono_monitor_enter_v4, "mono_monitor_enter_v4", "void obj ptr");
@@ -4102,6 +4118,10 @@ mini_cleanup (MonoDomain *domain)
        mono_os_mutex_destroy (&jit_mutex);
 
        mono_code_manager_cleanup ();
+
+#ifndef HOST_WIN32
+       mono_w32handle_cleanup ();
+#endif
 }
 
 void