2002-05-16 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mono / jit / jit.c
index 6a86784c0f85db3a379d65dc973f05e42da860fd..0cf36d3e6be55f8944a7282c95cd9b35c1f47221 100644 (file)
@@ -33,6 +33,7 @@
 #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
@@ -217,6 +218,9 @@ gboolean mono_use_fast_iconv = FALSE;
 /* 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;
 
@@ -228,17 +232,6 @@ int mono_debug_insert_breakpoint = 0;
 /* 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;
@@ -1063,6 +1056,10 @@ mono_cfg_new (MonoMethod *method, MonoMemPool *mp)
        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;
 
@@ -1098,7 +1095,7 @@ mono_cfg_free (MonoFlowGraph *cfg)
 }
 
 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;
@@ -1108,15 +1105,13 @@ mono_find_final_block (MonoFlowGraph *cfg, guint32 ip, int type)
 
        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;
@@ -1302,6 +1297,15 @@ mono_analyze_flow (MonoFlowGraph *cfg)
        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;
@@ -2933,28 +2937,6 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        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)
@@ -2964,6 +2946,9 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                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)
@@ -3080,7 +3065,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        /* 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;
@@ -3681,11 +3666,15 @@ mono_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[
        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
@@ -3737,36 +3726,39 @@ sigsegv_signal_handler (int _dummy)
 }
 
 /**
- * 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;
@@ -3815,11 +3807,8 @@ mono_jit_init (char *file) {
        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);
@@ -3828,7 +3817,7 @@ mono_jit_init (char *file) {
 
        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 ();