2009-01-29 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / aot-runtime.c
index 016061bd662c89fbec3ec26a2d14797bf9b74a98..8c988d0784245924a6c2f97bf400fd63bf83c61e 100644 (file)
@@ -1319,17 +1319,20 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
        return TRUE;
 }
 
+/*
+ * LOCKING: Acquires the domain lock.
+ */
 static MonoJitInfo*
 decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain, 
                                                         MonoMethod *method, guint8* ex_info, guint8 *code)
 {
        int i, buf_len;
        MonoJitInfo *jinfo;
-       guint code_len, used_int_regs;
-       gboolean has_generic_jit_info;
-       guint8 *p;
+       guint code_len, used_int_regs, flags;
+       gboolean has_generic_jit_info, has_dwarf_unwind_info;
+       guint8 *p, *unwind_info_block;
        MonoMethodHeader *header;
-       int generic_info_size;
+       int generic_info_size, unwind_info_len;
 
        header = mono_method_get_header (method);
 
@@ -1337,8 +1340,21 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
 
        p = ex_info;
        code_len = decode_value (p, &p);
-       used_int_regs = decode_value (p, &p);
-       has_generic_jit_info = decode_value (p, &p);
+       flags = decode_value (p, &p);
+       has_generic_jit_info = (flags & 1) != 0;
+       has_dwarf_unwind_info = (flags & 2) != 0;
+       unwind_info_block = p;
+       if (has_dwarf_unwind_info) {
+               gssize offset;
+
+               unwind_info_len = decode_value (p, &p);
+               offset = unwind_info_block - (guint8*)aot_module->ex_info;
+               g_assert (offset > 0 && offset < (1 << 30));
+               used_int_regs = offset;
+               p += unwind_info_len;
+       } else {
+               used_int_regs = decode_value (p, &p);
+       }
        if (has_generic_jit_info)
                generic_info_size = sizeof (MonoGenericJitInfo);
        else
@@ -1346,9 +1362,11 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
 
        /* Exception table */
        if (header && header->num_clauses) {
+               mono_domain_lock (domain);
                jinfo = 
                        mono_domain_alloc0 (domain, sizeof (MonoJitInfo) + (sizeof (MonoJitExceptionInfo) * header->num_clauses) + generic_info_size);
                jinfo->num_clauses = header->num_clauses;
+               mono_domain_unlock (domain);
 
                for (i = 0; i < header->num_clauses; ++i) {
                        MonoExceptionClause *ec = &header->clauses [i];                         
@@ -1367,14 +1385,18 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
                        ei->handler_start = code + decode_value (p, &p);
                }
        }
-       else
+       else {
+               mono_domain_lock (domain);
                jinfo = mono_domain_alloc0 (domain, sizeof (MonoJitInfo) + generic_info_size);
+               mono_domain_unlock (domain);
+       }
 
        jinfo->code_size = code_len;
        jinfo->used_regs = used_int_regs;
        jinfo->method = method;
        jinfo->code_start = code;
        jinfo->domain_neutral = 0;
+       jinfo->from_aot = 1;
 
        if (has_generic_jit_info) {
                MonoGenericJitInfo *gi;
@@ -1401,6 +1423,25 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
        return jinfo;
 }
 
+/*
+ * mono_aot_get_unwind_info:
+ *
+ *   Return a pointer to the DWARF unwind info belonging to JI.
+ */
+guint8*
+mono_aot_get_unwind_info (MonoJitInfo *ji, guint32 *unwind_info_len)
+{
+       MonoAotModule *amodule = ji->method->klass->image->aot_module;
+       guint8 *p;
+
+       g_assert (amodule);
+       g_assert (ji->from_aot);
+
+       p = amodule->ex_info + ji->used_regs;
+       *unwind_info_len = decode_value (p, &p);
+       return p;
+}
+
 MonoJitInfo *
 mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
 {
@@ -2001,10 +2042,6 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
                        mono_mempool_destroy (mp);
        }
 
-       mono_aot_lock ();
-
-       mono_jit_stats.methods_aot++;
-
        if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) {
                char *full_name;
 
@@ -2022,6 +2059,10 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
                g_free (full_name);
        }
 
+       mono_aot_lock ();
+
+       mono_jit_stats.methods_aot++;
+
        aot_module->methods_loaded [method_index / 32] |= 1 << (method_index % 32);
 
        init_plt (aot_module);
@@ -2068,6 +2109,18 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
                        char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
                        full_name = g_strdup_printf ("(wrapper runtime-invoke):%s (%s)", method->name, tmpsig);
                        g_free (tmpsig);
+               } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
+                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
+                       full_name = g_strdup_printf ("(wrapper delegate-invoke):%s (%s)", method->name, tmpsig);
+                       g_free (tmpsig);
+               } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_BEGIN_INVOKE) {
+                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
+                       full_name = g_strdup_printf ("(wrapper delegate-begin-invoke):%s (%s)", method->name, tmpsig);
+                       g_free (tmpsig);
+               } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_END_INVOKE) {
+                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
+                       full_name = g_strdup_printf ("(wrapper delegate-end-invoke):%s (%s)", method->name, tmpsig);
+                       g_free (tmpsig);
                } else {
                        full_name = mono_method_full_name (method, TRUE);
                }