From 698c995f5a0f9046aa4b3823b5018eae1412b8c9 Mon Sep 17 00:00:00 2001 From: Paolo Molaro Date: Thu, 19 Aug 2004 14:25:07 +0000 Subject: [PATCH] Thu Aug 19 17:26:55 CEST 2004 Paolo Molaro * 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 | 9 +++++ mono/mini/exceptions-amd64.c | 4 +++ mono/mini/exceptions-ppc.c | 70 +++++++++++++++++++++++------------- mono/mini/exceptions-s390.c | 14 ++++++-- mono/mini/exceptions-s390x.c | 14 ++++++-- mono/mini/exceptions-sparc.c | 4 +++ mono/mini/exceptions-x86.c | 4 +++ mono/mini/mini-exceptions.c | 42 ++++++++++++---------- 8 files changed, 113 insertions(+), 48 deletions(-) diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 27233047aa6..3e185d93b23 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,12 @@ + +Thu Aug 19 17:26:55 CEST 2004 Paolo Molaro + + * 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 * mini-amd64.c inssel-amd64.brg cpu-amd64.md: Merge changes from diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index cc9ee08a726..c9f2a02ad46 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -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); diff --git a/mono/mini/exceptions-ppc.c b/mono/mini/exceptions-ppc.c index 7f57d40dfc9..2a46dc0d187 100644 --- a/mono/mini/exceptions-ppc.c +++ b/mono/mini/exceptions-ppc.c @@ -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; } } diff --git a/mono/mini/exceptions-s390.c b/mono/mini/exceptions-s390.c index 61fd87bee07..30e062767ec 100644 --- a/mono/mini/exceptions-s390.c +++ b/mono/mini/exceptions-s390.c @@ -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; } diff --git a/mono/mini/exceptions-s390x.c b/mono/mini/exceptions-s390x.c index 0b4c920e084..45503d6cee9 100644 --- a/mono/mini/exceptions-s390x.c +++ b/mono/mini/exceptions-s390x.c @@ -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; } diff --git a/mono/mini/exceptions-sparc.c b/mono/mini/exceptions-sparc.c index a9b098a796a..aa4b46a9a96 100644 --- a/mono/mini/exceptions-sparc.c +++ b/mono/mini/exceptions-sparc.c @@ -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); diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index c0961c485d2..70df3fca38e 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -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); diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index f382d5e41b2..826709ad86d 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -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; } } -- 2.25.1