Merge pull request #1991 from esdrubal/seq_test_fix
[mono.git] / mono / mini / exceptions-sparc.c
index 184d28bdcc14d348b5eae91a48df571072d72213..b3b5633597644d39ff345274d0fc4f2749b21d66 100644 (file)
  * Returns a pointer to a method which restores a previously saved sigcontext.
  */
 gpointer
-mono_arch_get_restore_context (void)
+mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
 {
        static guint32 *start;
        static int inited = 0;
        guint32 *code;
 
+       g_assert (!aot);
+       if (info)
+               *info = NULL;
+
        if (inited)
                return start;
 
@@ -59,6 +63,8 @@ mono_arch_get_restore_context (void)
 
        g_assert ((code - start) < 32);
 
+       mono_arch_flush_icache ((guint8*)start, (guint8*)code - (guint8*)start);
+
        inited = 1;
 
        return start;
@@ -74,13 +80,17 @@ mono_arch_get_restore_context (void)
  * call_filter (MonoContext *ctx, gpointer ip)
  */
 gpointer
-mono_arch_get_call_filter (void)
+mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
 {
        static guint32 *start;
        static int inited = 0;
        guint32 *code;
        int i;
 
+       g_assert (!aot);
+       if (info)
+               *info = NULL;
+
        if (inited)
                return start;
 
@@ -146,6 +156,8 @@ mono_arch_get_call_filter (void)
 
        g_assert ((code - start) < 64);
 
+       mono_arch_flush_icache ((guint8*)start, (guint8*)code - (guint8*)start);
+
        inited = 1;
 
        return start;
@@ -159,7 +171,7 @@ throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow)
        gpointer *window;
        
        if (!restore_context)
-               restore_context = mono_arch_get_restore_context ();
+               restore_context = mono_get_restore_context ();
 
        window = MONO_SPARC_WINDOW_ADDR (sp);
        ctx.sp = (gpointer*)sp;
@@ -168,10 +180,12 @@ throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow)
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
-       mono_handle_exception (&ctx, exc, ip, FALSE);
+       mono_handle_exception (&ctx, exc);
        restore_context (&ctx);
 
        g_assert_not_reached ();
@@ -197,6 +211,8 @@ get_throw_exception (gboolean rethrow)
 
        g_assert ((code - start) <= 16);
 
+       mono_arch_flush_icache ((guint8*)start, (guint8*)code - (guint8*)start);
+
        return start;
 }
 
@@ -207,12 +223,16 @@ get_throw_exception (gboolean rethrow)
  * The returned function has the following 
  * signature: void (*func) (MonoException *exc); 
  */
-gpointer 
-mono_arch_get_throw_exception (void)
+gpointer
+mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
 {
        static guint32* start;
        static int inited = 0;
 
+       g_assert (!aot);
+       if (info)
+               *info = NULL;
+
        if (inited)
                return start;
 
@@ -223,69 +243,22 @@ mono_arch_get_throw_exception (void)
        return start;
 }
 
-gpointer 
-mono_arch_get_rethrow_exception (void)
+gpointer
+mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
 {
        static guint32* start;
        static int inited = 0;
 
-       if (inited)
-               return start;
-
-       inited = 1;
-
-       start = get_throw_exception (TRUE);
-
-       return start;
-}
-
-/**
- * mono_arch_get_throw_exception_by_name:
- *
- * Returns a function pointer which can be used to raise 
- * corlib exceptions. The returned function has the following 
- * signature: void (*func) (char *exc_name, gpointer ip); 
- */
-gpointer 
-mono_arch_get_throw_exception_by_name (void)
-{
-       static guint32 *start;
-       static int inited = 0;
-       guint32 *code;
-       int reg;
+       g_assert (!aot);
+       if (info)
+               *info = NULL;
 
        if (inited)
                return start;
 
        inited = 1;
-       code = start = mono_global_codeman_reserve (64 * sizeof (guint32));
-
-#ifdef SPARCV9
-       reg = sparc_g4;
-#else
-       reg = sparc_g1;
-#endif
-
-       sparc_save_imm (code, sparc_sp, -160, sparc_sp);
-
-       sparc_mov_reg_reg (code, sparc_i0, sparc_o2);
-       sparc_set (code, mono_defaults.corlib, sparc_o0);
-       sparc_set (code, "System", sparc_o1);
-       sparc_set (code, mono_exception_from_name, sparc_o7);
-       sparc_jmpl (code, sparc_o7, sparc_g0, sparc_callsite);
-       sparc_nop (code);
-
-       /* Return to the caller, so exception handling does not see this frame */
-       sparc_restore (code, sparc_o0, sparc_g0, sparc_o0);
-
-       /* Put original return address into %o7 */
-       sparc_mov_reg_reg (code, sparc_o1, sparc_o7);
-       sparc_set (code, mono_arch_get_throw_exception (), reg);
-       /* Use a jmp instead of a call so o7 is preserved */
-       sparc_jmpl_imm (code, reg, 0, sparc_g0);
-       sparc_nop (code);
 
-       g_assert ((code - start) < 32);
+       start = get_throw_exception (TRUE);
 
        return start;
 }
@@ -300,14 +273,18 @@ mono_arch_get_throw_exception_by_name (void)
  * to get the IP of the throw. Passing the offset has the advantage that it 
  * needs no relocations in the caller.
  */
-gpointer 
-mono_arch_get_throw_corlib_exception (void)
+gpointer
+mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
 {
        static guint32 *start;
        static int inited = 0;
        guint32 *code;
        int reg;
 
+       g_assert (!aot);
+       if (info)
+               *info = NULL;
+
        if (inited)
                return start;
 
@@ -337,17 +314,19 @@ mono_arch_get_throw_corlib_exception (void)
        sparc_sll_imm (code, sparc_o1, 2, sparc_o1);
        sparc_sub (code, 0, sparc_o2, sparc_o1, sparc_o7);
 
-       sparc_set (code, mono_arch_get_throw_exception (), reg);
+       sparc_set (code, mono_arch_get_throw_exception (NULL, FALSE), reg);
        /* Use a jmp instead of a call so o7 is preserved */
        sparc_jmpl_imm (code, reg, 0, sparc_g0);
        sparc_nop (code);
 
        g_assert ((code - start) < 32);
 
+       mono_arch_flush_icache ((guint8*)start, (guint8*)code - (guint8*)start);
+
        return start;
 }
 
-/* mono_arch_find_jit_info:
+/* mono_arch_unwind_frame:
  *
  * This function is used to gather information from @ctx. It return the 
  * MonoJitInfo of the corresponding function, unwinds one stack frame and
@@ -356,35 +335,25 @@ mono_arch_get_throw_corlib_exception (void)
  * the @lmf if necessary. @native_offset return the IP offset from the 
  * start of the function or -1 if that info is not available.
  */
-MonoJitInfo *
-mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, 
-                        MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset,
-                        gboolean *managed)
+gboolean
+mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, 
+                                                        MonoJitInfo *ji, MonoContext *ctx, 
+                                                        MonoContext *new_ctx, MonoLMF **lmf,
+                                                        mgreg_t **save_locations,
+                                                        StackFrameInfo *frame)
 {
-       MonoJitInfo *ji;
-       gpointer ip = MONO_CONTEXT_GET_IP (ctx);
        gpointer *window;
 
-       /* Avoid costly table lookup during stack overflow */
-       if (prev_ji && (ip > prev_ji->code_start && ((guint8*)ip < ((guint8*)prev_ji->code_start) + prev_ji->code_size)))
-               ji = prev_ji;
-       else
-               ji = mono_jit_info_table_find (domain, ip);
+       memset (frame, 0, sizeof (StackFrameInfo));
+       frame->ji = ji;
 
-       if (managed)
-               *managed = FALSE;
+       *new_ctx = *ctx;
 
        if (ji != NULL) {
-               *new_ctx = *ctx;
-
-               if (managed)
-                       if (!ji->method->wrapper_type)
-                               *managed = TRUE;
-
-               if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
-                       /* remove any unused lmf */
-                       *lmf = (*lmf)->previous_lmf;
-               }
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                /* Restore ip and sp from the saved register window */
                window = MONO_SPARC_WINDOW_ADDR (ctx->sp);
@@ -392,22 +361,21 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                new_ctx->sp = (gpointer*)(window [sparc_i6 - 16]);
                new_ctx->fp = (gpointer*)(MONO_SPARC_WINDOW_ADDR (new_ctx->sp) [sparc_i6 - 16]);
 
-               return ji;
+               return TRUE;
        }
        else {
                if (!(*lmf))
-                       return NULL;
-
-               *new_ctx = *ctx;
+                       return FALSE;
 
                if (!(*lmf)->method)
-                       return (gpointer)-1;
+                       return FALSE;
 
-               if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->ip))) {
-               } else {
-                       memset (res, 0, sizeof (MonoJitInfo));
-                       res->method = (*lmf)->method;
-               }
+               ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->ip, NULL);
+               if (!ji)
+                       return FALSE;
+
+               frame->ji = ji;
+               frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
 
                new_ctx->ip = (*lmf)->ip;
                new_ctx->sp = (*lmf)->sp;
@@ -415,20 +383,14 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
 
                *lmf = (*lmf)->previous_lmf;
 
-               return ji ? ji : res;
+               return TRUE;
        }
 }
 
-gboolean
-mono_arch_has_unwind_info (gconstpointer addr)
-{
-       return FALSE;
-}
-
 #ifdef __linux__
 
 gboolean
-mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+mono_arch_handle_exception (void *sigctx, gpointer obj)
 {
        MonoContext mctx;
        struct sigcontext *sc = sigctx;
@@ -445,7 +407,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
        window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
        mctx.fp = window [sparc_fp - 16];
 
-       mono_handle_exception (&mctx, obj, mctx.ip, test_only);
+       mono_handle_exception (&mctx, obj);
 
 #ifdef SPARCV9
        sc->sigc_regs.tpc = (unsigned long) mctx.ip;
@@ -481,7 +443,7 @@ mono_arch_ip_from_context (void *sigctx)
 #else /* !__linux__ */
 
 gboolean
-mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+mono_arch_handle_exception (void *sigctx, gpointer obj)
 {
        MonoContext mctx;
        ucontext_t *ctx = (ucontext_t*)sigctx;
@@ -499,7 +461,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
        window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
        mctx.fp = window [sparc_fp - 16];
 
-       mono_handle_exception (&mctx, obj, mctx.ip, test_only);
+       mono_handle_exception (&mctx, obj);
        
        /* We can't use restore_context to return from a signal handler */
        ctx->uc_mcontext.gregs [REG_PC] = mctx.ip;