Merge pull request #5560 from kumpera/wasm-work-p3
[mono.git] / mono / mini / mini-exceptions.c
index c8a71c69378dac317a72716a0aa8cccb1182bc29..707951af02e15c807e7eccced069307a22af527b 100644 (file)
 #define MONO_ARCH_CONTEXT_DEF
 #endif
 
-#ifndef MONO_ARCH_STACK_GROWS_UP
-#define MONO_ARCH_STACK_GROWS_UP 0
-#endif
-
 /*
  * Raw frame information is stored in MonoException.trace_ips as an IntPtr[].
  * This structure represents one entry.
@@ -149,18 +145,6 @@ mono_thread_get_managed_sp (void)
        return addr;
 }
 
-static inline int
-mini_abort_threshold_offset (gpointer threshold, gpointer sp)
-{
-       intptr_t stack_threshold = (intptr_t) threshold;
-       intptr_t stack_pointer = (intptr_t) sp;
-
-       const int direction = MONO_ARCH_STACK_GROWS_UP ? -1 : 1;
-       intptr_t magnitude = stack_pointer - stack_threshold;
-
-       return direction * magnitude;
-}
-
 static inline void
 mini_clear_abort_threshold (void)
 {
@@ -176,7 +160,7 @@ mini_set_abort_threshold (MonoContext *ctx)
        // Only move it up, to avoid thrown/caught
        // exceptions lower in the stack from triggering
        // a rethrow
-       gboolean above_threshold = mini_abort_threshold_offset (jit_tls->abort_exc_stack_threshold, sp) >= 0;
+       gboolean above_threshold = (gsize) sp >= (gsize) jit_tls->abort_exc_stack_threshold;
        if (!jit_tls->abort_exc_stack_threshold || above_threshold) {
                jit_tls->abort_exc_stack_threshold = sp;
        }
@@ -194,7 +178,7 @@ mini_above_abort_threshold (void)
        if (!sp)
                return TRUE;
 
-       gboolean above_threshold = mini_abort_threshold_offset (jit_tls->abort_exc_stack_threshold, sp) >= 0;
+       gboolean above_threshold = (gsize) sp >= (gsize) jit_tls->abort_exc_stack_threshold;
 
        if (above_threshold)
                jit_tls->abort_exc_stack_threshold = sp;
@@ -251,10 +235,13 @@ mono_exceptions_init (void)
 
        cbs.mono_walk_stack_with_state = mono_walk_stack_with_state;
 
-       if (mono_llvm_only)
+       if (mono_llvm_only) {
                cbs.mono_raise_exception = mono_llvm_raise_exception;
-       else
+               cbs.mono_reraise_exception = mono_llvm_reraise_exception;
+       } else {
                cbs.mono_raise_exception = (void (*)(MonoException *))mono_get_throw_exception ();
+               cbs.mono_reraise_exception = (void (*)(MonoException *))mono_get_rethrow_exception ();
+       }
        cbs.mono_raise_exception_with_ctx = mono_raise_exception_with_ctx;
        cbs.mono_exception_walk_trace = mono_exception_walk_trace;
        cbs.mono_install_handler_block_guard = mono_install_handler_block_guard;
@@ -1428,6 +1415,11 @@ wrap_non_exception_throws (MonoMethod *m)
        int i;
        gboolean val = FALSE;
 
+       if (m->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) {
+               MonoDynamicMethod *dm = (MonoDynamicMethod *)m;
+               if (dm->assembly)
+                       ass = dm->assembly;
+       }
        g_assert (ass);
        if (ass->wrap_non_exception_throws_inited)
                return ass->wrap_non_exception_throws;
@@ -1682,10 +1674,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi
                        dynamic_methods = g_slist_prepend (dynamic_methods, method);
 
                if (stack_overflow) {
-                       if (MONO_ARCH_STACK_GROWS_UP)
-                               free_stack = (guint8*)(MONO_CONTEXT_GET_SP (&initial_ctx)) - (guint8*)(MONO_CONTEXT_GET_SP (ctx));
-                       else
-                               free_stack = (guint8*)(MONO_CONTEXT_GET_SP (ctx)) - (guint8*)(MONO_CONTEXT_GET_SP (&initial_ctx));
+                       free_stack = (guint8*)(MONO_CONTEXT_GET_SP (ctx)) - (guint8*)(MONO_CONTEXT_GET_SP (&initial_ctx));
                } else {
                        free_stack = 0xffffff;
                }
@@ -1716,7 +1705,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi
 
                                if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
 #ifndef DISABLE_PERFCOUNTERS
-                                       mono_perfcounters->exceptions_filters++;
+                                       InterlockedIncrement (&mono_perfcounters->exceptions_filters);
 #endif
 
 #ifndef MONO_CROSS_COMPILE
@@ -2041,10 +2030,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                //printf ("M: %s %d.\n", mono_method_full_name (method, TRUE), frame_count);
 
                if (stack_overflow) {
-                       if (MONO_ARCH_STACK_GROWS_UP)
-                               free_stack = (guint8*)(MONO_CONTEXT_GET_SP (&initial_ctx)) - (guint8*)(MONO_CONTEXT_GET_SP (ctx));
-                       else
-                               free_stack = (guint8*)(MONO_CONTEXT_GET_SP (ctx)) - (guint8*)(MONO_CONTEXT_GET_SP (&initial_ctx));
+                       free_stack = (guint8*)(MONO_CONTEXT_GET_SP (ctx)) - (guint8*)(MONO_CONTEXT_GET_SP (&initial_ctx));
                } else {
                        free_stack = 0xffffff;
                }
@@ -2172,7 +2158,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                        }
                                        mono_set_lmf (lmf);
 #ifndef DISABLE_PERFCOUNTERS
-                                       mono_perfcounters->exceptions_depth += frame_count;
+                                       InterlockedAdd (&mono_perfcounters->exceptions_depth, frame_count);
 #endif
                                        if (obj == (MonoObject *)domain->stack_overflow_ex)
                                                jit_tls->handling_stack_ovf = FALSE;
@@ -2186,8 +2172,6 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                        jit_tls->orig_ex_ctx_set = TRUE;
                                        MONO_PROFILER_RAISE (exception_clause, (method, i, ei->flags, ex_obj));
                                        jit_tls->orig_ex_ctx_set = FALSE;
-                                       mini_set_abort_threshold (ctx);
-                                       call_filter (ctx, ei->handler_start);
                                }
                                if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
                                        if (mono_trace_is_enabled () && mono_trace_eval (method))
@@ -2196,8 +2180,10 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                        MONO_PROFILER_RAISE (exception_clause, (method, i, ei->flags, ex_obj));
                                        jit_tls->orig_ex_ctx_set = FALSE;
 #ifndef DISABLE_PERFCOUNTERS
-                                       mono_perfcounters->exceptions_finallys++;
+                                       InterlockedIncrement (&mono_perfcounters->exceptions_finallys);
 #endif
+                               }
+                               if (ei->flags == MONO_EXCEPTION_CLAUSE_FAULT || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
                                        mono_set_lmf (lmf);
                                        if (ji->from_llvm) {
                                                /* 
@@ -2230,9 +2216,12 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                        }
                }
 
-               jit_tls->orig_ex_ctx_set = TRUE;
-               MONO_PROFILER_RAISE (method_exception_leave, (method, ex_obj));
-               jit_tls->orig_ex_ctx_set = FALSE;
+               if (MONO_PROFILER_ENABLED (method_exception_leave) &&
+                   mono_profiler_get_call_instrumentation_flags (method) & MONO_PROFILER_CALL_INSTRUMENTATION_EXCEPTION_LEAVE) {
+                       jit_tls->orig_ex_ctx_set = TRUE;
+                       MONO_PROFILER_RAISE (method_exception_leave, (method, ex_obj));
+                       jit_tls->orig_ex_ctx_set = FALSE;
+               }
 
                *ctx = new_ctx;
        }
@@ -2293,7 +2282,7 @@ mono_handle_exception (MonoContext *ctx, MonoObject *obj)
        MONO_REQ_GC_UNSAFE_MODE;
 
 #ifndef DISABLE_PERFCOUNTERS
-       mono_perfcounters->exceptions_thrown++;
+       InterlockedIncrement (&mono_perfcounters->exceptions_thrown);
 #endif
 
        return mono_handle_exception_internal (ctx, obj, FALSE, NULL);
@@ -2706,12 +2695,12 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T
                 * glibc fork acquires some locks, so if the crash happened inside malloc/free,
                 * it will deadlock. Call the syscall directly instead.
                 */
-#if defined(PLATFORM_ANDROID)
+#if defined(HOST_ANDROID)
                /* SYS_fork is defined to be __NR_fork which is not defined in some ndk versions */
                g_assert_not_reached ();
-#elif !defined(PLATFORM_MACOSX) && defined(SYS_fork)
+#elif !defined(HOST_DARWIN) && defined(SYS_fork)
                pid = (pid_t) syscall (SYS_fork);
-#elif defined(PLATFORM_MACOSX) && HAVE_FORK
+#elif defined(HOST_DARWIN) && HAVE_FORK
                pid = (pid_t) fork ();
 #else
                g_assert_not_reached ();
@@ -2739,7 +2728,7 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T
 #endif
  }
 #else
-#ifdef PLATFORM_ANDROID
+#ifdef HOST_ANDROID
        /* set DUMPABLE for this process so debuggerd can attach with ptrace(2), see:
         * https://android.googlesource.com/platform/bionic/+/151da681000c07da3c24cd30a3279b1ca017f452/linker/debugger.cpp#206
         * this has changed on later versions of Android.  Also, we don't want to
@@ -2779,7 +2768,7 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T
 
        if (!mono_do_crash_chaining) {
                /*Android abort is a fluke, it doesn't abort, it triggers another segv. */
-#if defined (PLATFORM_ANDROID)
+#if defined (HOST_ANDROID)
                exit (-1);
 #else
                abort ();
@@ -2842,7 +2831,7 @@ mono_print_thread_dump_internal (void *sigctx, MonoContext *start_ctx)
 
        mono_runtime_printf ("%s", text->str);
 
-#if PLATFORM_WIN32 && TARGET_WIN32 && _DEBUG
+#if HOST_WIN32 && TARGET_WIN32 && _DEBUG
        OutputDebugStringA(text->str);
 #endif
 
@@ -3236,6 +3225,12 @@ mono_llvm_raise_exception (MonoException *e)
        mono_llvm_throw_exception ((MonoObject*)e);
 }
 
+void
+mono_llvm_reraise_exception (MonoException *e)
+{
+       mono_llvm_rethrow_exception ((MonoObject*)e);
+}
+
 void
 mono_llvm_throw_corlib_exception (guint32 ex_token_index)
 {
@@ -3273,7 +3268,7 @@ mono_llvm_load_exception (void)
 
        if (mono_ex->trace_ips) {
                GList *trace_ips = NULL;
-               gpointer ip = __builtin_return_address (0);
+               gpointer ip = MONO_RETURN_ADDRESS ();
 
                size_t upper = mono_array_length (mono_ex->trace_ips);