#include <mono/metadata/appdomain.h>
#include <mono/arch/x86/x86-codegen.h>
#include <mono/io-layer/io-layer.h>
+#include <mono/io-layer/threads.h>
#include "jit.h"
#include "regset.h"
#include "debug.h"
/*
- * if OPT_BOOL is defined we use 32bit to store boolean local variables.
- * This gives great speedup for boolean expressions
- */
-#define OPT_BOOL
+ * if OPT_BOOL is defined we use 32bit to store boolean local variables. This
+ * gives great speedup for boolean expressions, but unfortunately it changes
+ * semantics, so i disable it until we have a real solution */
+/* #define OPT_BOOL */
/* this is x86 specific */
#define MB_TERM_LDIND_REF MB_TERM_LDIND_I4
/* maximum number of worker threads */
int mono_worker_threads = 1;
+/* TLS id to store jit data */
+guint32 mono_jit_tls_id;
+
MonoDebugHandle *mono_debug_handle = NULL;
GList *mono_debug_methods = NULL;
/* This is the address of the last breakpoint which was inserted. */
gchar *mono_debug_last_breakpoint_address = NULL;
-gpointer mono_end_of_stack = NULL;
-
-/* last managed frame (used by pinvoke) */
-guint32 lmf_thread_id = 0;
-
-/* used to store a function pointer called after uncatched exceptions */
-guint32 exc_cleanup_id = 0;
-
-/* stores a pointer to async result used by exceptions */
-guint32 async_result_id = 0;
-
MonoJitStats mono_jit_stats;
CRITICAL_SECTION *metadata_section = NULL;
cfg->method = method;
cfg->mp = mp;
+ /* reserve space for caller saved registers */
+ /* fixme: this is arch dependent */
+ cfg->locals_size = 12;
+
/* fixme: we should also consider loader optimisation attributes */
cfg->share_code = mono_jit_share_code;
}
static MonoBBlock *
-mono_find_final_block (MonoFlowGraph *cfg, guint32 ip, int type)
+mono_find_final_block (MonoFlowGraph *cfg, guint32 ip, guint32 target, int type)
{
MonoMethod *method = cfg->method;
MonoBytecodeInfo *bcinfo = cfg->bcinfo;
for (i = 0; i < header->num_clauses; ++i) {
clause = &header->clauses [i];
- if (MONO_OFFSET_IN_HANDLER (clause, ip))
- continue;
- if (MONO_OFFSET_IN_CLAUSE (clause, ip)) {
+ if (MONO_OFFSET_IN_CLAUSE (clause, ip) &&
+ (!MONO_OFFSET_IN_CLAUSE (clause, target))) {
if (clause->flags & type) {
g_assert (bcinfo [clause->handler_offset].is_block_start);
return &cfg->bblocks [bcinfo [clause->handler_offset].block_id];
- } else
- return NULL;
+ }
}
}
return NULL;
cfg->bblocks = bblocks;
cfg->block_count = block_count;
+ for (i = 0; i < header->num_clauses; ++i) {
+ MonoBBlock *sbb, *tbb;
+ clause = &header->clauses [i];
+ sbb = &cfg->bblocks [bcinfo [clause->try_offset].block_id];
+ tbb = &cfg->bblocks [bcinfo [clause->handler_offset].block_id];
+ g_assert (sbb && tbb);
+ sbb->succ = g_list_prepend (sbb->succ, tbb);
+ }
+
ip = header->code;
end = ip + header->code_size;
bb = NULL;
break;
}
- case CEE_SHR: {
- ++ip;
- sp -= 2;
- t1 = mono_ctree_new (mp, MB_TERM_SHR, sp [0], sp [1]);
- PUSH_TREE (t1, sp [0]->svt);
- break;
- }
- case CEE_SHR_UN: {
- ++ip;
- sp -= 2;
- t1 = mono_ctree_new (mp, MB_TERM_SHR_UN, sp [0], sp [1]);
- PUSH_TREE (t1, sp [0]->svt);
- break;
- }
- case CEE_SHL: {
- ++ip;
- sp -= 2;
- t1 = mono_ctree_new (mp, MB_TERM_SHL, sp [0], sp [1]);
- PUSH_TREE (t1, sp [0]->svt);
- break;
- }
-
MAKE_BI_ALU (ADD)
MAKE_BI_ALU (ADD_OVF)
MAKE_BI_ALU (ADD_OVF_UN)
MAKE_BI_ALU (AND)
MAKE_BI_ALU (OR)
MAKE_BI_ALU (XOR)
+ MAKE_SPILLED_BI_ALU (SHL)
+ MAKE_SPILLED_BI_ALU (SHR)
+ MAKE_SPILLED_BI_ALU (SHR_UN)
MAKE_SPILLED_BI_ALU (MUL)
MAKE_SPILLED_BI_ALU (MUL_OVF)
MAKE_SPILLED_BI_ALU (MUL_OVF_UN)
/* fixme: fault handler */
- if ((hb = mono_find_final_block (cfg, cli_addr, MONO_EXCEPTION_CLAUSE_FINALLY))) {
+ if ((hb = mono_find_final_block (cfg, cli_addr, target, MONO_EXCEPTION_CLAUSE_FINALLY))) {
mark_reached (cfg, hb, NULL, 0);
t1 = mono_ctree_new_leaf (mp, MB_TERM_HANDLER);
t1->data.p = hb;
MonoImage *image = assembly->image;
MonoCLIImageInfo *iinfo;
MonoMethod *method;
+ MonoObject *exc;
+ int rval;
iinfo = image->image_info;
method = mono_get_method (image, iinfo->cli_cli_header.ch_entry_point, NULL);
- return mono_runtime_run_main (method, argc, argv);
+ rval = mono_runtime_run_main (method, argc, argv, &exc);
+
+ return rval;
}
#ifdef PLATFORM_WIN32
}
/**
- * mono_jit_abort:
+ * mono_thread_abort:
* @obj: exception object
*
- * abort the program, print exception information and stack trace
+ * abort the thread, print exception information and stack trace
*/
static void
-mono_jit_abort (MonoObject *obj)
+mono_thread_abort (MonoObject *obj)
{
- const char *message = "";
- char *trace = NULL;
- MonoString *str; ;
-
+ MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+
g_assert (obj);
- if (mono_object_isinst (obj, mono_defaults.exception_class)) {
- if ((str = ((MonoException *)obj)->message))
- message = mono_string_to_utf8 (str);
- if ((str = ((MonoException *)obj)->stack_trace))
- trace = mono_string_to_utf8 (str);
- }
-
- g_warning ("unhandled exception %s.%s: \"%s\"", obj->vtable->klass->name_space,
- obj->vtable->klass->name, message);
-
- if (trace) {
- g_printerr (trace);
- g_printerr ("\n");
+ if (jit_tls->env) {
+ longjmp (*jit_tls->env, obj);
}
+
+ if (obj)
+ mono_unhandled_exception (obj);
+
+ ExitThread (-1);
+}
+
+static void
+mono_thread_start_cb (gpointer stack_start)
+{
+ MonoJitTlsData *jit_tls;
+
+ jit_tls = g_new0 (MonoJitTlsData, 1);
+
+ TlsSetValue (mono_jit_tls_id, jit_tls);
- exit (1);
+ jit_tls->abort_func = mono_thread_abort;
+ jit_tls->end_of_stack = stack_start;
}
static CRITICAL_SECTION ms;
metadata_section = &ms;
InitializeCriticalSection (metadata_section);
- lmf_thread_id = TlsAlloc ();
- TlsSetValue (lmf_thread_id, NULL);
- exc_cleanup_id = TlsAlloc ();
- TlsSetValue (exc_cleanup_id, mono_jit_abort);
- async_result_id = TlsAlloc ();
+ mono_jit_tls_id = TlsAlloc ();
+ mono_thread_start_cb (&file);
mono_install_trampoline (arch_create_jit_trampoline);
mono_install_remoting_trampoline (arch_create_remoting_trampoline);
domain = mono_init (file);
mono_runtime_init (domain);
- mono_thread_init (domain);
+ mono_thread_init (domain, mono_thread_start_cb);
mono_network_init ();
mono_delegate_init ();