[runtime] Fix handler block
[mono.git] / mono / mini / mini-exceptions.c
index 2b8374596e0f30adefe21b196d3c2f1857bd90b9..d73c4c8e462dd16dfa9dca540fe95066f2823734 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>
@@ -120,6 +120,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)
@@ -349,7 +350,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;
@@ -1937,7 +1938,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);
@@ -2106,11 +2107,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) {
@@ -2130,7 +2132,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*/
                                                }
@@ -2139,7 +2140,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, ex_obj);
+                                       MONO_PROFILER_RAISE (exception_clause, (method, i, ei->flags, ex_obj));
                                        jit_tls->orig_ex_ctx_set = FALSE;
                                        mini_set_abort_threshold (ctx);
 
@@ -2183,7 +2184,7 @@ 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, ex_obj);
+                                       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);
@@ -2192,7 +2193,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                        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, ex_obj);
+                                       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++;
@@ -2230,7 +2231,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                }
 
                jit_tls->orig_ex_ctx_set = TRUE;
-               mono_profiler_exception_method_leave (method);
+               MONO_PROFILER_RAISE (method_exception_leave, (method, ex_obj));
                jit_tls->orig_ex_ctx_set = FALSE;
 
                *ctx = new_ctx;
@@ -2890,8 +2891,6 @@ mono_resume_unwind (MonoContext *ctx)
        mono_restore_context (&new_ctx);
 }
 
-#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
-
 typedef struct {
        MonoJitInfo *ji;
        MonoContext ctx;
@@ -2917,7 +2916,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;
@@ -2928,12 +2927,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);
 
@@ -2941,30 +2941,27 @@ 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)
@@ -2974,7 +2971,7 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
        /* 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 */
@@ -2987,11 +2984,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;
@@ -3001,24 +2995,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)
 {