Thu Aug 19 17:26:55 CEST 2004 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Thu, 19 Aug 2004 14:25:07 +0000 (14:25 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Thu, 19 Aug 2004 14:25:07 +0000 (14:25 -0000)
* mini-exceptions.c, exceptions-x86.c, exceptions-amd64.c,
exceptions-ppc.c, exceptions-s390.c, exceptions-s390x.c,
exceptions-sparc.c: fix some performance issues in exception
handling and setting of the stack trace for exceptions that were
already thrown.

svn path=/trunk/mono/; revision=32531

mono/mini/ChangeLog
mono/mini/exceptions-amd64.c
mono/mini/exceptions-ppc.c
mono/mini/exceptions-s390.c
mono/mini/exceptions-s390x.c
mono/mini/exceptions-sparc.c
mono/mini/exceptions-x86.c
mono/mini/mini-exceptions.c

index 27233047aa637aadef123092bd7560ddaa4b1acc..3e185d93b23f66932ed949f67514ff89b0ba7a63 100644 (file)
@@ -1,3 +1,12 @@
+
+Thu Aug 19 17:26:55 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+       * mini-exceptions.c, exceptions-x86.c, exceptions-amd64.c,
+       exceptions-ppc.c, exceptions-s390.c, exceptions-s390x.c,
+       exceptions-sparc.c: fix some performance issues in exception
+       handling and setting of the stack trace for exceptions that were
+       already thrown.
+
 2004-08-18  Zoltan Varga  <vargaz@freemail.hu>
 
        * mini-amd64.c inssel-amd64.brg cpu-amd64.md: Merge changes from 
index cc9ee08a726d13bef9ba405b18124ddd1db36876..c9f2a02ad46a5a67dda8989c39abf467df0ff756 100644 (file)
@@ -284,6 +284,10 @@ throw_exception (MonoObject *exc, guint64 rip, guint64 rsp,
        ctx.r14 = r14;
        ctx.r15 = r15;
 
+       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+               MonoException *mono_ex = (MonoException*)exc;
+               mono_ex->stack_trace = NULL;
+       }
        mono_handle_exception (&ctx, exc, (gpointer)(rip + 1), FALSE);
        restore_context (&ctx);
 
index 7f57d40dfc9b0cd7cd50ff519c6efbf7656d32c0..2a46dc0d187458bc076e60dc16bde49d7a74289a 100644 (file)
@@ -315,6 +315,10 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gulong *
        memcpy (&ctx.regs, int_regs, sizeof (gulong) * MONO_SAVED_GREGS);
        memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_SAVED_FREGS);
 
+       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+               MonoException *mono_ex = (MonoException*)exc;
+               mono_ex->stack_trace = NULL;
+       }
        arch_handle_exception (&ctx, exc, FALSE);
        restore_context (&ctx);
 
@@ -837,7 +841,9 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
        MonoLMF *lmf = jit_tls->lmf;            
        GList *trace_ips = NULL;
        MonoException *mono_ex;
-       MonoString *initial_stack_trace;
+       MonoString *initial_stack_trace = NULL;
+       GString *trace_str = NULL;
+       int frame_count = 0;
 
        g_assert (ctx != NULL);
        if (!obj) {
@@ -878,34 +884,30 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
        while (1) {
                MonoContext new_ctx;
                char *trace = NULL;
+               gboolean need_trace = FALSE;
                
+               if (test_only && (frame_count < 1000)) {
+                       need_trace = TRUE;
+                       if (!trace_str)
+                               trace_str = g_string_new ("");
+               }
                setup_context (&new_ctx);
                ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &rji, ctx, &new_ctx, 
-                                             test_only ? &trace : NULL, &lmf, NULL, NULL);
+                                             need_trace ? &trace : NULL, &lmf, NULL, NULL);
                if (!ji) {
                        g_warning ("Exception inside function without unwind info");
                        g_assert_not_reached ();
                }
 
                if (ji != (gpointer)-1) {
+                       frame_count ++;
                        
                        if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) {
-                               char *tmp, *strace;
-
-                               if (!initial_stack_trace) {
-                                       trace_ips = g_list_append (trace_ips, MONO_CONTEXT_GET_IP (ctx));
-
-                                       if (!mono_ex->stack_trace)
-                                               strace = g_strdup ("");
-                                       else
-                                               strace = mono_string_to_utf8 (mono_ex->stack_trace);
-                       
-                                       tmp = g_strdup_printf ("%s%s\n", strace, trace);
-                                       g_free (strace);
-
-                                       mono_ex->stack_trace = mono_string_new (domain, tmp);
+                               if (!initial_stack_trace && (frame_count < 1000)) {
+                                       trace_ips = g_list_prepend (trace_ips, MONO_CONTEXT_GET_IP (ctx));
 
-                                       g_free (tmp);
+                                       g_string_append (trace_str, trace);
+                                       g_string_append_c (trace_str, '\n');
                                }
                        }
 
@@ -920,25 +922,41 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                                        if (ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
                                            MONO_CONTEXT_GET_IP (ctx) <= ei->try_end) { 
                                                /* catch block */
+
+                                               if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)) {
+                                                       /* store the exception object int cfg->excvar */
+                                                       g_assert (ji->exvar_offset);
+                                                       /* need to use the frame pointer (ppc_r31), not r1 (regs start from register r13): methods with clauses always have r31 */
+                                                       *((gpointer *)((char *)(ctx->regs [ppc_r31-13]) + ji->exvar_offset)) = obj;
+                                                       if (!initial_stack_trace && trace_str) {
+                                                               mono_ex->stack_trace = mono_string_new (domain, trace_str->str);
+                                                       }
+                                               }
+
+                                               if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)
+                                                       filtered = call_filter (ctx, ei->data.filter);
+
                                                if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE && 
-                                                    mono_object_isinst (obj, mono_class_get (ji->method->klass->image, ei->data.token))) ||
-                                                   ((ei->flags == MONO_EXCEPTION_CLAUSE_FILTER &&
-                                                     call_filter (ctx, ei->data.filter, obj)))) {
+                                                    mono_object_isinst (obj, mono_class_get (ji->method->klass->image, ei->data.token))) || filtered) {
                                                        if (test_only) {
-                                                               if (mono_ex)
+                                                               if (mono_ex) {
+                                                                       trace_ips = g_list_reverse (trace_ips);
                                                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                                                               }
                                                                g_list_free (trace_ips);
                                                                g_free (trace);
+                                                               if (trace_str)
+                                                                       g_string_free (trace_str, TRUE);
                                                                return TRUE;
                                                        }
                                                        if (mono_jit_trace_calls != NULL)
                                                                g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
                                                        /*printf ("stack for catch: %p\n", MONO_CONTEXT_GET_BP (ctx));*/
                                                        MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
-                                                       /* need to use the frame pointer (ppc_r31), not r1 (regs start from register r13): methods with clauses always have r31 */
-                                                       *((gpointer *)((char *)(ctx->regs [ppc_r31-13]) + ji->exvar_offset)) = obj;
                                                        jit_tls->lmf = lmf;
                                                        g_free (trace);
+                                                       if (trace_str)
+                                                               g_string_free (trace_str, TRUE);
                                                        return 0;
                                                }
                                                if (!test_only && ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
@@ -965,9 +983,13 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                                jit_tls->abort_func (obj);
                                g_assert_not_reached ();
                        } else {
-                               if (mono_ex)
+                               if (mono_ex) {
+                                       trace_ips = g_list_reverse (trace_ips);
                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                               }
                                g_list_free (trace_ips);
+                               if (trace_str)
+                                       g_string_free (trace_str, TRUE);
                                return FALSE;
                        }
                }
index 61fd87bee07ee1284b5390c6fc13a9e59bea81b7..30e062767ec07e077648ee0ddaa75a1db5788d65 100644 (file)
@@ -500,6 +500,10 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp,
        MONO_CONTEXT_SET_BP (&ctx, sp);
        MONO_CONTEXT_SET_IP (&ctx, ip);
        
+       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+               MonoException *mono_ex = (MonoException*)exc;
+               mono_ex->stack_trace = NULL;
+       }
        mono_arch_handle_exception (&ctx, exc, FALSE);
        setcontext(&ctx);
 
@@ -1048,7 +1052,7 @@ mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
                        if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) {
                                char *tmp, *strace;
 
-                               trace_ips = g_list_append (trace_ips, MONO_CONTEXT_GET_IP (ctx));
+                               trace_ips = g_list_prepend (trace_ips, MONO_CONTEXT_GET_IP (ctx));
 
                                if (!mono_ex->stack_trace)
                                        strace = g_strdup ("");
@@ -1079,8 +1083,10 @@ mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
                                                    ((ei->flags == MONO_EXCEPTION_CLAUSE_FILTER &&
                                                      call_filter (ctx, ei->data.filter, obj)))) {
                                                        if (test_only) {
-                                                               if (mono_ex)
+                                                               if (mono_ex) {
+                                                                       trace_ips = g_list_reverse (trace_ips);
                                                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                                                               }
                                                                g_list_free (trace_ips);
                                                                g_free (trace);
                                                                return TRUE;
@@ -1123,8 +1129,10 @@ mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
                                jit_tls->abort_func (obj);
                                g_assert_not_reached ();
                        } else {
-                               if (mono_ex)
+                               if (mono_ex) {
+                                       trace_ips = g_list_reverse (trace_ips);
                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                               }
                                g_list_free (trace_ips);
                                return FALSE;
                        }
index 0b4c920e084c37a9d42df6fd36b53e226eb638cb..45503d6cee9b3727427674845492497a377d1238 100644 (file)
@@ -480,6 +480,10 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp,
        MONO_CONTEXT_SET_BP (&ctx, sp);
        MONO_CONTEXT_SET_IP (&ctx, ip);
        
+       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+               MonoException *mono_ex = (MonoException*)exc;
+               mono_ex->stack_trace = NULL;
+       }
        mono_arch_handle_exception (&ctx, exc, FALSE);
        setcontext(&ctx);
 
@@ -1028,7 +1032,7 @@ mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
                        if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) {
                                char *tmp, *strace;
 
-                               trace_ips = g_list_append (trace_ips, MONO_CONTEXT_GET_IP (ctx));
+                               trace_ips = g_list_prepend (trace_ips, MONO_CONTEXT_GET_IP (ctx));
 
                                if (!mono_ex->stack_trace)
                                        strace = g_strdup ("");
@@ -1059,8 +1063,10 @@ mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
                                                    ((ei->flags == MONO_EXCEPTION_CLAUSE_FILTER &&
                                                      call_filter (ctx, ei->data.filter, obj)))) {
                                                        if (test_only) {
-                                                               if (mono_ex)
+                                                               if (mono_ex) {
+                                                                       trace_ips = g_list_reverse (trace_ips);
                                                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                                                               }
                                                                g_list_free (trace_ips);
                                                                g_free (trace);
                                                                return TRUE;
@@ -1103,8 +1109,10 @@ mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
                                jit_tls->abort_func (obj);
                                g_assert_not_reached ();
                        } else {
-                               if (mono_ex)
+                               if (mono_ex) {
+                                       trace_ips = g_list_reverse (trace_ips);
                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                               }
                                g_list_free (trace_ips);
                                return FALSE;
                        }
index a9b098a796aeee816fea4f0a2f63641245dc18ad..aa4b46a9a963978c3f52d6161abdb3e0968da260 100644 (file)
@@ -165,6 +165,10 @@ throw_exception (MonoObject *ex, gpointer sp, gpointer ip)
        ctx.ip = ip;
        ctx.fp = (gpointer*)(MONO_SPARC_WINDOW_ADDR (sp) [sparc_i6 - 16]);
 
+       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+               MonoException *mono_ex = (MonoException*)exc;
+               mono_ex->stack_trace = NULL;
+       }
        mono_handle_exception (&ctx, ex, ip, FALSE);
        restore_context (&ctx);
 
index c0961c485d2861b4cf572dae98a7d95c17b2474f..70df3fca38e73579023c74b284d396ac216760ff 100644 (file)
@@ -248,6 +248,10 @@ throw_exception (unsigned long eax, unsigned long ecx, unsigned long edx, unsign
        ctx.SC_ECX = ecx;
        ctx.SC_EAX = eax;
        
+       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+               MonoException *mono_ex = (MonoException*)exc;
+               mono_ex->stack_trace = NULL;
+       }
        mono_handle_exception (&ctx, exc, eip + 1, FALSE);
        restore_context (&ctx);
 
index f382d5e41b2acface36ec51bc62342a29f880388..826709ad86d7452c1949487f801a4396157b469a 100644 (file)
@@ -205,7 +205,8 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
        MonoContext initial_ctx;
        int frame_count = 0;
        gboolean gc_disabled = FALSE;
-       MonoString *initial_stack_trace;
+       MonoString *initial_stack_trace = NULL;
+       GString *trace_str = NULL;
        
        /*
         * This function might execute on an alternate signal stack, and Boehm GC
@@ -294,8 +295,11 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
                gboolean need_trace = FALSE;
                guint32 free_stack;
 
-               if (test_only && (frame_count < 1000))
+               if (test_only && (frame_count < 1000)) {
                        need_trace = TRUE;
+                       if (!trace_str)
+                               trace_str = g_string_new ("");
+               }
 
                ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &rji, ctx, &new_ctx, 
                                              need_trace ? &trace : NULL, &lmf, NULL, NULL);
@@ -309,27 +313,16 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
                        //printf ("M: %s %d %d.\n", mono_method_full_name (ji->method, TRUE), frame_count, test_only);
 
                        if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) {
-                               char *tmp, *strace;
-
                                /* 
                                 * Avoid overwriting the stack trace if the exception is
                                 * rethrown. Also avoid giant stack traces during a stack
                                 * overflow.
                                 */
                                if (!initial_stack_trace && (frame_count < 1000)) {
-                                       trace_ips = g_list_append (trace_ips, MONO_CONTEXT_GET_IP (ctx));
-
-                                       if (!mono_ex->stack_trace)
-                                               strace = g_strdup ("");
-                                       else
-                                               strace = mono_string_to_utf8 (mono_ex->stack_trace);
-
-                                       tmp = g_strdup_printf ("%s%s\n", strace, trace);
-                                       g_free (strace);
+                                       trace_ips = g_list_prepend (trace_ips, MONO_CONTEXT_GET_IP (ctx));
 
-                                       mono_ex->stack_trace = mono_string_new (domain, tmp);
-
-                                       g_free (tmp);
+                                       g_string_append (trace_str, trace);
+                                       g_string_append_c (trace_str, '\n');
                                }
                        }
 
@@ -359,6 +352,9 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
                                                        /* store the exception object int cfg->excvar */
                                                        g_assert (ji->exvar_offset);
                                                        *((gpointer *)((char *)MONO_CONTEXT_GET_BP (ctx) + ji->exvar_offset)) = obj;
+                                                       if (!initial_stack_trace && trace_str) {
+                                                               mono_ex->stack_trace = mono_string_new (domain, trace_str->str);
+                                                       }
                                                }
 
                                                if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)
@@ -367,13 +363,17 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
                                                if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE && 
                                                     mono_object_isinst (obj, mono_class_get (ji->method->klass->image, ei->data.token))) || filtered) {
                                                        if (test_only) {
-                                                               if (mono_ex)
+                                                               if (mono_ex) {
+                                                                       trace_ips = g_list_reverse (trace_ips);
                                                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                                                               }
                                                                g_list_free (trace_ips);
                                                                g_free (trace);
 
                                                                if (gc_disabled)
                                                                        mono_gc_enable ();
+                                                               if (trace_str)
+                                                                       g_string_free (trace_str, TRUE);
                                                                return TRUE;
                                                        }
                                                        if (mono_jit_trace_calls != NULL && mono_trace_eval (ji->method))
@@ -384,6 +384,8 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
 
                                                        if (gc_disabled)
                                                                mono_gc_enable ();
+                                                       if (trace_str)
+                                                               g_string_free (trace_str, TRUE);
                                                        return 0;
                                                }
                                                if (!test_only && ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
@@ -422,9 +424,13 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gpointer original_ip, gbo
                                        jit_tls->abort_func (obj);
                                g_assert_not_reached ();
                        } else {
-                               if (mono_ex)
+                               if (mono_ex) {
+                                       trace_ips = g_list_reverse (trace_ips);
                                        mono_ex->trace_ips = glist_to_array (trace_ips);
+                               }
                                g_list_free (trace_ips);
+                               if (trace_str)
+                                       g_string_free (trace_str, TRUE);
                                return FALSE;
                        }
                }