Merge pull request #5560 from kumpera/wasm-work-p3
[mono.git] / mono / mini / mini-exceptions.c
index 099e6e10dd03ccda34fd010318f18e52b37674e5..707951af02e15c807e7eccced069307a22af527b 100644 (file)
@@ -60,7 +60,7 @@
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/debug-internals.h>
 #include <mono/metadata/mono-debug.h>
-#include <mono/metadata/profiler.h>
+#include <mono/metadata/profiler-private.h>
 #include <mono/metadata/mono-endian.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/mono-mlist.h>
 #include "mini-llvm-cpp.h"
 #endif
 
+#ifdef TARGET_ARM
+#include "mini-arm.h"
+#endif
+
 #ifndef MONO_ARCH_CONTEXT_DEF
 #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.
+ * This should consists of pointers only.
+ */
+typedef struct
+{
+       gpointer ip;
+       gpointer generic_info;
+}  ExceptionTraceIp;
+
+/* Number of words in trace_ips belonging to one entry */
+#define TRACE_IP_ENTRY_SIZE (sizeof (ExceptionTraceIp) / sizeof (gpointer))
 
 static gpointer restore_context_func, call_filter_func;
 static gpointer throw_exception_func, rethrow_exception_func;
@@ -102,6 +116,7 @@ static void mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx,
 static void mono_raise_exception_with_ctx (MonoException *exc, MonoContext *ctx);
 static void mono_runtime_walk_stack_with_ctx (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data);
 static gboolean mono_current_thread_has_handle_block_guard (void);
+static gboolean mono_install_handler_block_guard (MonoThreadUnwindState *ctx);
 
 static gboolean
 first_managed (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer addr)
@@ -130,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)
 {
@@ -157,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;
        }
@@ -175,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;
@@ -232,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;
@@ -331,7 +337,7 @@ is_address_protected (MonoJitInfo *ji, MonoJitExceptionInfo *ei, gpointer ip)
 
        for (i = 0; i < table->num_holes; ++i) {
                MonoTryBlockHoleJitInfo *hole = &table->holes [i];
-               if (hole->clause == clause && hole->offset <= offset && hole->offset + hole->length > offset)
+               if (ji->clauses [hole->clause].try_offset == ji->clauses [clause].try_offset && hole->offset <= offset && hole->offset + hole->length > offset)
                        return FALSE;
        }
        return TRUE;
@@ -826,10 +832,13 @@ mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpoin
        if (ta == NULL)
                return FALSE;
 
-       len = mono_array_length (ta) >> 1;
+       len = mono_array_length (ta) / TRACE_IP_ENTRY_SIZE;
        for (i = 0; i < len; i++) {
-               gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0);
-               gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1);
+               ExceptionTraceIp trace_ip;
+
+               memcpy (&trace_ip, mono_array_addr_fast (ta, ExceptionTraceIp, i), sizeof (ExceptionTraceIp));
+               gpointer ip = trace_ip.ip;
+               gpointer generic_info = trace_ip.generic_info;
                MonoJitInfo *ji = mono_jit_info_table_find (domain, (char *)ip);
 
                if (ji == NULL) {
@@ -862,7 +871,7 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info
                return res;
        }
 
-       len = mono_array_length (ta) >> 1;
+       len = mono_array_length (ta) / TRACE_IP_ENTRY_SIZE;
 
        res = mono_array_new_checked (domain, mono_defaults.stack_frame_class, len > skip ? len - skip : 0, &error);
        if (mono_error_set_pending_exception (&error))
@@ -875,8 +884,10 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info
                        mono_error_set_pending_exception (&error);
                        return NULL;
                }
-               gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0);
-               gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1);
+               ExceptionTraceIp trace_ip;
+               memcpy (&trace_ip, mono_array_addr_fast (ta, ExceptionTraceIp, i), sizeof (ExceptionTraceIp));
+               gpointer ip = trace_ip.ip;
+               gpointer generic_info = trace_ip.generic_info;
                MonoMethod *method;
 
                ji = mono_jit_info_table_find (domain, (char *)ip);
@@ -1066,6 +1077,7 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
        mgreg_t *new_reg_locations [MONO_MAX_IREGS];
        gboolean get_reg_locations = unwind_options & MONO_UNWIND_REG_LOCATIONS;
        gboolean async = mono_thread_info_is_async_context ();
+       Unwinder unwinder;
 
        if (mono_llvm_only) {
                GSList *l, *ips;
@@ -1110,9 +1122,11 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
        memcpy (&ctx, start_ctx, sizeof (MonoContext));
        memset (reg_locations, 0, sizeof (reg_locations));
 
+       unwinder_init (&unwinder);
+
        while (MONO_CONTEXT_GET_SP (&ctx) < jit_tls->end_of_stack) {
                frame.lmf = lmf;
-               res = mono_find_jit_info_ext (domain, jit_tls, NULL, &ctx, &new_ctx, NULL, &lmf, get_reg_locations ? new_reg_locations : NULL, &frame);
+               res = unwinder_unwind_frame (&unwinder, domain, jit_tls, NULL, &ctx, &new_ctx, NULL, &lmf, get_reg_locations ? new_reg_locations : NULL, &frame);
                if (!res)
                        return;
 
@@ -1401,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;
@@ -1559,13 +1578,13 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi
        mono_ex = (MonoException*)obj;
        MonoArray *initial_trace_ips = mono_ex->trace_ips;
        if (initial_trace_ips) {
-               int len = mono_array_length (initial_trace_ips) >> 1;
+               int len = mono_array_length (initial_trace_ips) / TRACE_IP_ENTRY_SIZE;
 
                for (i = 0; i < (len - 1); i++) {
-                       gpointer ip = mono_array_get (initial_trace_ips, gpointer, i * 2 + 0);
-                       gpointer generic_info = mono_array_get (initial_trace_ips, gpointer, i * 2 + 1);
-                       trace_ips = g_list_prepend (trace_ips, ip);
-                       trace_ips = g_list_prepend (trace_ips, generic_info);
+                       for (int j = 0; j < TRACE_IP_ENTRY_SIZE; ++j) {
+                               gpointer p = mono_array_get (initial_trace_ips, gpointer, (i * TRACE_IP_ENTRY_SIZE) + j);
+                               trace_ips = g_list_prepend (trace_ips, p);
+                       }
                }
        }
 
@@ -1629,7 +1648,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi
 
                gpointer ip;
                if (in_interp)
-                       ip = (guint16*)ji->code_start + frame.native_offset;
+                       ip = (guint8*)ji->code_start + frame.native_offset;
                else
                        ip = MONO_CONTEXT_GET_IP (ctx);
 
@@ -1655,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;
                }
@@ -1689,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
@@ -1911,7 +1927,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                mono_print_thread_dump_from_ctx (ctx);
                }
                jit_tls->orig_ex_ctx_set = TRUE;
-               mono_profiler_exception_thrown (obj);
+               MONO_PROFILER_RAISE (exception_throw, (obj));
                jit_tls->orig_ex_ctx_set = FALSE;
 
                res = mono_handle_exception_internal_first_pass (&ctx_cp, obj, &first_filter_idx, &ji, &prev_ji, non_exception);
@@ -2005,7 +2021,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                }
 
                if (in_interp)
-                       ip = (guint16*)ji->code_start + frame.native_offset;
+                       ip = (guint8*)ji->code_start + frame.native_offset;
                else
                        ip = MONO_CONTEXT_GET_IP (ctx);
 
@@ -2014,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;
                }
@@ -2080,11 +2093,12 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                         * that was called by the EH machinery. It won't have a guard trampoline installed, so we must
                                         * check for this situation here and resume interruption if we are below the guarded block.
                                         */
-                                       if (G_UNLIKELY (jit_tls->handler_block_return_address)) {
+                                       if (G_UNLIKELY (jit_tls->handler_block)) {
                                                gboolean is_outside = FALSE;
                                                gpointer prot_bp = MONO_CONTEXT_GET_BP (&jit_tls->handler_block_context);
                                                gpointer catch_bp = MONO_CONTEXT_GET_BP (ctx);
                                                //FIXME make this stack direction aware
+
                                                if (catch_bp > prot_bp) {
                                                        is_outside = TRUE;
                                                } else if (catch_bp == prot_bp) {
@@ -2104,7 +2118,6 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                                        }
                                                }
                                                if (is_outside) {
-                                                       jit_tls->handler_block_return_address = NULL;
                                                        jit_tls->handler_block = NULL;
                                                        mono_thread_resume_interruption (TRUE); /*We ignore the exception here, it will be raised later*/
                                                }
@@ -2113,7 +2126,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                        if (mono_trace_is_enabled () && mono_trace_eval (method))
                                                g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (method, TRUE));
                                        jit_tls->orig_ex_ctx_set = TRUE;
-                                       mono_profiler_exception_clause_handler (method, ei->flags, i);
+                                       MONO_PROFILER_RAISE (exception_clause, (method, i, ei->flags, ex_obj));
                                        jit_tls->orig_ex_ctx_set = FALSE;
                                        mini_set_abort_threshold (ctx);
 
@@ -2127,10 +2140,16 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                                 * like the call which transitioned to JITted code has succeeded, but the
                                                 * return value register etc. is not set, so we have to be careful.
                                                 */
-                                               mono_interp_set_resume_state (mono_ex, &frame, ei->handler_start);
+                                               mono_interp_set_resume_state (jit_tls, mono_ex, frame.interp_frame, ei->handler_start);
                                                /* Undo the IP adjustment done by mono_arch_unwind_frame () */
-#ifdef TARGET_AMD64
+#if defined(TARGET_AMD64)
                                                ctx->gregs [AMD64_RIP] ++;
+#elif defined(TARGET_ARM)
+                                               ctx->pc ++;
+                                               if (mono_arm_thumb_supported ())
+                                                       ctx->pc |= 1;
+#elif defined(TARGET_ARM64)
+                                               ctx->pc ++;
 #else
                                                NOT_IMPLEMENTED;
 #endif
@@ -2139,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;
@@ -2151,20 +2170,20 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                        if (mono_trace_is_enabled () && mono_trace_eval (method))
                                                g_print ("EXCEPTION: fault clause %d of %s\n", i, mono_method_full_name (method, TRUE));
                                        jit_tls->orig_ex_ctx_set = TRUE;
-                                       mono_profiler_exception_clause_handler (method, ei->flags, i);
+                                       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))
                                                g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (method, TRUE));
                                        jit_tls->orig_ex_ctx_set = TRUE;
-                                       mono_profiler_exception_clause_handler (method, ei->flags, i);
+                                       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) {
                                                /* 
@@ -2197,9 +2216,12 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                        }
                }
 
-               jit_tls->orig_ex_ctx_set = TRUE;
-               mono_profiler_exception_method_leave (method);
-               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;
        }
@@ -2250,6 +2272,9 @@ mono_debugger_run_finally (MonoContext *start_ctx)
  * mono_handle_exception:
  * \param ctx saved processor state
  * \param obj the exception object
+ *
+ *   Handle the exception OBJ starting from the state CTX. Modify CTX to point to the handler clause if the exception is caught, and
+ * return TRUE.
  */
 gboolean
 mono_handle_exception (MonoContext *ctx, MonoObject *obj)
@@ -2257,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);
@@ -2598,7 +2623,7 @@ static void print_process_map (void)
 #endif
 }
 
-static gboolean handling_sigsegv = FALSE;
+static gboolean handle_crash_loop = FALSE;
 
 /*
  * mono_handle_native_crash:
@@ -2614,9 +2639,7 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T
 #endif
        MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls ();
 
-       gboolean is_sigsegv = !strcmp ("SIGSEGV", signal);
-
-       if (handling_sigsegv && is_sigsegv)
+       if (handle_crash_loop)
                return;
 
        if (mini_get_debug_options ()->suspend_on_native_crash) {
@@ -2631,9 +2654,8 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T
 #endif
        }
 
-       /* To prevent infinite loops when the stack walk causes a crash */
-       if (is_sigsegv)
-               handling_sigsegv = TRUE;
+       /* prevent infinite loops in crash handling */
+       handle_crash_loop = TRUE;
 
        /* !jit_tls means the thread was not registered with the runtime */
        if (jit_tls && mono_thread_internal_current ()) {
@@ -2673,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 ();
@@ -2706,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
@@ -2746,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 ();
@@ -2809,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
 
@@ -2858,8 +2880,6 @@ mono_resume_unwind (MonoContext *ctx)
        mono_restore_context (&new_ctx);
 }
 
-#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
-
 typedef struct {
        MonoJitInfo *ji;
        MonoContext ctx;
@@ -2885,7 +2905,7 @@ find_last_handler_block (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
                        continue;
                /*If ip points to the first instruction it means the handler block didn't start
                 so we can leave its execution to the EH machinery*/
-               if (ei->handler_start < ip && ip < ei->data.handler_end) {
+               if (ei->handler_start <= ip && ip < ei->data.handler_end) {
                        pdata->ji = ji;
                        pdata->ei = ei;
                        pdata->ctx = *ctx;
@@ -2896,12 +2916,13 @@ find_last_handler_block (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
 }
 
 
-static gpointer
+static void
 install_handler_block_guard (MonoJitInfo *ji, MonoContext *ctx)
 {
        int i;
        MonoJitExceptionInfo *clause = NULL;
        gpointer ip;
+       guint8 *bp;
 
        ip = MONO_CONTEXT_GET_IP (ctx);
 
@@ -2909,40 +2930,32 @@ install_handler_block_guard (MonoJitInfo *ji, MonoContext *ctx)
                clause = &ji->clauses [i];
                if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY)
                        continue;
-               if (clause->handler_start < ip && clause->data.handler_end > ip)
+               if (clause->handler_start <= ip && clause->data.handler_end > ip)
                        break;
        }
 
        /*no matching finally */
        if (i == ji->num_clauses)
-               return NULL;
-
-       /*If we stopped on the instruction right before the try, we haven't actually started executing it*/
-       if (ip == clause->handler_start)
-               return NULL;
+               return;
 
-       return mono_arch_install_handler_block_guard (ji, clause, ctx, mono_create_handler_block_trampoline ());
+        /*Load the spvar*/
+        bp = (guint8*)MONO_CONTEXT_GET_BP (ctx);
+        *(bp + clause->exvar_offset) = 1;
 }
 
 /*
  * Finds the bottom handler block running and install a block guard if needed.
  */
-gboolean
+static gboolean
 mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
 {
        FindHandlerBlockData data = { 0 };
        MonoJitTlsData *jit_tls = (MonoJitTlsData *)ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS];
-       gpointer resume_ip;
-
-#ifndef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT
-       if (mono_aot_only)
-               return FALSE;
-#endif
 
        /* Guard against a null MonoJitTlsData. This can happens if the thread receives the
          * interrupt signal before the JIT has time to initialize its TLS data for the given thread.
         */
-       if (!jit_tls || jit_tls->handler_block_return_address)
+       if (!jit_tls || jit_tls->handler_block)
                return FALSE;
 
        /* Do an async safe stack walk */
@@ -2955,11 +2968,8 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
 
        memcpy (&jit_tls->handler_block_context, &data.ctx, sizeof (MonoContext));
 
-       resume_ip = install_handler_block_guard (data.ji, &data.ctx);
-       if (resume_ip == NULL)
-               return FALSE;
+       install_handler_block_guard (data.ji, &data.ctx);
 
-       jit_tls->handler_block_return_address = resume_ip;
        jit_tls->handler_block = data.ei;
 
        return TRUE;
@@ -2969,24 +2979,9 @@ static gboolean
 mono_current_thread_has_handle_block_guard (void)
 {
        MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls ();
-       return jit_tls && jit_tls->handler_block_return_address != NULL;
-}
-
-#else
-gboolean
-mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
-{
-       return FALSE;
+       return jit_tls && jit_tls->handler_block != NULL;
 }
 
-static gboolean
-mono_current_thread_has_handle_block_guard (void)
-{
-       return FALSE;
-}
-
-#endif
-
 void
 mono_set_cast_details (MonoClass *from, MonoClass *to)
 {
@@ -3230,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)
 {
@@ -3267,16 +3268,16 @@ 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);
 
-               for (int i = 0; i < upper; i+= 2) {
+               for (int i = 0; i < upper; i += TRACE_IP_ENTRY_SIZE) {
                        gpointer curr_ip = mono_array_get (mono_ex->trace_ips, gpointer, i);
-                       gpointer curr_info = mono_array_get (mono_ex->trace_ips, gpointer, i + 1);
-                       trace_ips = g_list_append (trace_ips, curr_ip);
-                       trace_ips = g_list_append (trace_ips, curr_info);
-
+                       for (int j = 0; j < TRACE_IP_ENTRY_SIZE; ++j) {
+                               gpointer p = mono_array_get (mono_ex->trace_ips, gpointer, i + j);
+                               trace_ips = g_list_append (trace_ips, p);
+                       }
                        if (ip == curr_ip)
                                break;
                }
@@ -3397,31 +3398,3 @@ mono_debug_personality (void)
        g_assert_not_reached ();
 }
 #endif
-
-#ifndef ENABLE_INTERPRETER
-/* Stubs of interpreter functions */
-void
-mono_interp_set_resume_state (MonoException *ex, StackFrameInfo *frame, gpointer handler_ip)
-{
-       g_assert_not_reached ();
-}
-
-void
-mono_interp_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip)
-{
-       g_assert_not_reached ();
-}
-
-void
-mono_interp_frame_iter_init (MonoInterpStackIter *iter, gpointer interp_exit_data)
-{
-       g_assert_not_reached ();
-}
-
-gboolean
-mono_interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame)
-{
-       g_assert_not_reached ();
-       return FALSE;
-}
-#endif