+
+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
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);
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);
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) {
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');
}
}
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) &&
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;
}
}
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);
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 ("");
((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;
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;
}
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);
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 ("");
((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;
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;
}
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);
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);
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
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);
//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');
}
}
/* 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)
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))
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) &&
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;
}
}