2010-01-20 Zoltan Varga <vargaz@gmail.com>
+ * exceptions-<ARCH>.c: Introduce a MONO_ARCH_HAVE_THROW_EXCEPTION_BY_NAME
+ define for platforms still using it (s390). Get rid of the
+ mono_arch_get_throw_exception_by_name () routines on all other platforms.
+
* exceptions-x86.c: Rework the throw trampolines so there is only one function
which can generate throw/rethrow/corlib trampolines for llvm/not llvm code.
* mini-llvm.c: Enable throwing exceptions on x86.
- * mini-posix.c (SIG_HANDLER_SIGNATURE): Avoid
+ * mini-posix.c (SIG_HANDLER_SIGNATURE): Avoid
"Thread (nil) may have been prematurely finalized" messages if this is called
on a thread not registered with the runtime.
emit_trampoline (acfg, "throw_exception", code, code_size, acfg->got_offset, ji, NULL);
code = mono_arch_get_rethrow_exception_full (&code_size, &ji, TRUE);
emit_trampoline (acfg, "rethrow_exception", code, code_size, acfg->got_offset, ji, NULL);
+#ifdef MONO_ARCH_HAVE_THROW_EXCEPTION_BY_NAME
code = mono_arch_get_throw_exception_by_name_full (&code_size, &ji, TRUE);
emit_trampoline (acfg, "throw_exception_by_name", code, code_size, acfg->got_offset, ji, NULL);
+#endif
code = mono_arch_get_throw_corlib_exception_full (&code_size, &ji, TRUE);
emit_trampoline (acfg, "throw_corlib_exception", code, code_size, acfg->got_offset, ji, NULL);
return get_throw_trampoline (TRUE, code_size, ji, aot);
}
-gpointer
-mono_arch_get_throw_exception_by_name_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
-{
- guint8* start;
- guint8 *code;
-
- start = code = mono_global_codeman_reserve (64);
-
- *ji = NULL;
-
- /* Not used on amd64 */
- amd64_breakpoint (code);
-
- mono_arch_flush_icache (start, code - start);
-
- *code_size = code - start;
-
- return start;
-}
-
/**
* mono_arch_get_throw_corlib_exception:
*
return mono_arch_get_throw_exception_generic (132, FALSE, FALSE, code_size, ji, aot);
}
-gpointer
-mono_arch_get_throw_exception_by_name_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
-{
- guint8* start;
- guint8 *code;
-
- *ji = NULL;
-
- start = code = mono_global_codeman_reserve (64);
-
- /* Not used on ARM */
- ARM_DBRK (code);
-
- *code_size = code - start;
-
- return start;
-}
-
/**
* mono_arch_get_throw_corlib_exception:
*
return start;
}
-gpointer
-mono_arch_get_throw_exception_by_name (void)
-{
- guint8* start;
- Ia64CodegenState code;
-
- start = mono_global_codeman_reserve (64);
-
- /* Not used on ia64 */
- ia64_codegen_init (code, start);
- ia64_break_i (code, 1001);
- ia64_codegen_close (code);
-
- g_assert ((code.buf - start) <= 256);
-
- mono_arch_flush_icache (start, code.buf - start);
-
- return start;
-}
-
/**
* mono_arch_get_throw_corlib_exception:
*
return mono_arch_get_throw_exception_generic (size, code_size, ji, FALSE, FALSE, aot);
}
-/**
- * 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);
- * For example to raise an arithmetic exception you can use:
- *
- * x86_push_imm (code, "ArithmeticException");
- * x86_call_code (code, arch_get_throw_exception_by_name ());
- *
- */
-gpointer
-mono_arch_get_throw_exception_by_name_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
-{
- guint8 *start, *code;
- int size = 64;
-
- *ji = NULL;
-
- /* Not used on PPC */
- start = code = mono_global_codeman_reserve (size);
- ppc_break (code);
- mono_arch_flush_icache (start, code - start);
- *code_size = code - start;
- return start;
-}
-
/**
* mono_arch_get_throw_corlib_exception:
*
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;
-
- 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);
-
- mono_arch_flush_icache ((guint8*)start, (guint8*)code - (guint8*)start);
-
- return start;
-}
-
/**
* mono_arch_get_throw_corlib_exception:
*
return get_throw_exception ("rethrow_exception_trampoline", TRUE, FALSE, FALSE);
}
-/**
- * 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) (gpointer ip, char *exc_name);
- * For example to raise an arithmetic exception you can use:
- *
- * x86_push_imm (code, "ArithmeticException");
- * x86_push_imm (code, <IP>)
- * x86_jump_code (code, arch_get_throw_exception_by_name ());
- *
- */
-gpointer
-mono_arch_get_throw_exception_by_name (void)
-{
- guint8* start;
- guint8 *code;
-
- start = code = mono_global_codeman_reserve (32);
-
- /* Not used */
- x86_breakpoint (code);
-
- mono_arch_flush_icache (start, code - start);
-
- return start;
-}
-
/**
* mono_arch_get_throw_corlib_exception:
*
gpointer
mono_get_throw_exception_by_name (void)
{
+#ifdef MONO_ARCH_HAVE_THROW_EXCEPTION_BY_NAME
+
gpointer code = NULL;
#ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
guint32 code_size;
throw_exception_by_name_func = code;
+#else
+
+ throw_exception_by_name_func = NULL;
+
+ g_assert_not_reached ();
+#endif
+
return throw_exception_by_name_func;
}
// #define MONO_ARCH_SIGSEGV_ON_ALTSTACK 1
// #define MONO_ARCH_SIGNAL_STACK_SIZE 65536
// #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
+#define MONO_ARCH_HAVE_THROW_EXCEPTION_BY_NAME 1
#define MONO_ARCH_USE_SIGACTION 1
#define MONO_ARCH_SIGNAL_STACK_SIZE 256*1024
#define MONO_ARCH_HAVE_DECOMPOSE_OPTS 1
// #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
+#define MONO_ARCH_HAVE_THROW_EXCEPTION_BY_NAME 1
#define MONO_ARCH_USE_SIGACTION 1
register_icall (mono_get_throw_exception (), "mono_arch_throw_exception", "void object", TRUE);
register_icall (mono_get_rethrow_exception (), "mono_arch_rethrow_exception", "void object", TRUE);
+#ifdef MONO_ARCH_HAVE_THROW_EXCEPTION_BY_NAME
register_icall (mono_get_throw_exception_by_name (), "mono_arch_throw_exception_by_name", "void ptr", TRUE);
+#endif
#if MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION
register_icall (mono_get_throw_corlib_exception (), "mono_arch_throw_corlib_exception",
"void ptr", TRUE);