2007-12-02 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sun, 2 Dec 2007 13:53:14 +0000 (13:53 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 2 Dec 2007 13:53:14 +0000 (13:53 -0000)
* patch-info.h (PATCH_INFO): Add DELEGATE_TRAMPOLINE.

* mini.c aot-compiler.c aot-runtime.c: Implement the delegate creation
optimization in the AOT case.

svn path=/trunk/mono/; revision=90521

mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini.c
mono/mini/patch-info.h

index 1ebe735e51ecdcc3edc5c5a728889b0964609554..4d8b299d3eba8d3d559c114b7dbcc1a513186304 100644 (file)
@@ -2070,6 +2070,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
                }
                break;
        case MONO_PATCH_INFO_CLASS_INIT:
+       case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
                encode_klass_ref (acfg, patch_info->data.klass, p, &p);
                break;
        case MONO_PATCH_INFO_FIELD:
@@ -2784,6 +2785,7 @@ compile_method (MonoAotCompile *acfg, int index)
                        break;
                case MONO_PATCH_INFO_VTABLE:
                case MONO_PATCH_INFO_CLASS_INIT:
+               case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
                case MONO_PATCH_INFO_CLASS:
                case MONO_PATCH_INFO_IID:
                case MONO_PATCH_INFO_ADJUSTED_IID:
index ed4629645296fa309dc8c86d69a1961008b3ca70..9d30751635390f1851100cfda26f0053159b5832 100644 (file)
@@ -1282,6 +1282,7 @@ decode_patch_info (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji,
                }
                break;
        case MONO_PATCH_INFO_CLASS_INIT:
+       case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
                ji->data.klass = decode_klass_ref (aot_module, p, &p);
                if (!ji->data.klass)
                        goto cleanup;
index ceea4215b589a01f3f5e8cea8f5f24d8f71ada88..05affdd06706ae757706c205ede5e979769eb3eb 100644 (file)
@@ -173,6 +173,7 @@ static int mini_verbose = 0;
 static CRITICAL_SECTION jit_mutex;
 
 static GHashTable *class_init_hash_addr = NULL;
+static GHashTable *delegate_trampoline_hash_addr = NULL;
 
 static MonoCodeManager *global_codeman = NULL;
 
@@ -3131,7 +3132,7 @@ handle_delegate_ctor (MonoCompile *cfg, MonoBasicBlock *bblock, MonoClass *klass
        ins->inst_right = offset_ins;
 
        trampoline = mono_create_delegate_trampoline (klass);
-       NEW_PCONST (cfg, tramp_ins, trampoline);
+       NEW_AOTCONST (cfg, tramp_ins, MONO_PATCH_INFO_ABS, trampoline);
 
        MONO_INST_NEW (cfg, store, CEE_STIND_I);
        store->cil_code = ip;
@@ -7942,9 +7943,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                 * Optimize the common case of ldftn+delegate creation
                                 */
 #if defined(MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE) && !defined(HAVE_WRITE_BARRIERS)
-                               /* FIXME: AOT */
                                /* FIXME: SGEN support */
-                               if ((sp > stack_start) && (ip + 6 + 5 < end) && ip_in_bb (cfg, bblock, ip + 6) && (ip [6] == CEE_NEWOBJ) && (ctor_method = mini_get_method (method, read32 (ip + 7), NULL, generic_context)) && (ctor_method->klass->parent == mono_defaults.multicastdelegate_class) && !cfg->compile_aot) {
+                               if ((sp > stack_start) && (ip + 6 + 5 < end) && ip_in_bb (cfg, bblock, ip + 6) && (ip [6] == CEE_NEWOBJ) && (ctor_method = mini_get_method (method, read32 (ip + 7), NULL, generic_context)) && (ctor_method->klass->parent == mono_defaults.multicastdelegate_class)) {
                                        MonoInst *target_ins;
 
                                        ip += 6;
@@ -8834,6 +8834,12 @@ mono_create_delegate_trampoline (MonoClass *klass)
                                                          klass, ptr);
        mono_domain_unlock (domain);
 
+       mono_jit_lock ();
+       if (!delegate_trampoline_hash_addr)
+               delegate_trampoline_hash_addr = g_hash_table_new (NULL, NULL);
+       g_hash_table_insert (delegate_trampoline_hash_addr, ptr, klass);
+       mono_jit_unlock ();
+
        return ptr;
 #else
        return NULL;
@@ -8854,6 +8860,20 @@ mono_find_class_init_trampoline_by_addr (gconstpointer addr)
        return res;
 }
 
+static MonoClass*
+mono_find_delegate_trampoline_by_addr (gconstpointer addr)
+{
+       MonoClass *res;
+
+       mono_jit_lock ();
+       if (delegate_trampoline_hash_addr)
+               res = g_hash_table_lookup (delegate_trampoline_hash_addr, addr);
+       else
+               res = NULL;
+       mono_jit_unlock ();
+       return res;
+}
+
 static void
 mono_dynamic_code_hash_insert (MonoDomain *domain, MonoMethod *method, MonoJitDynamicMethodInfo *ji)
 {
@@ -9763,6 +9783,9 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
        case MONO_PATCH_INFO_CLASS_INIT:
                target = mono_create_class_init_trampoline (mono_class_vtable (domain, patch_info->data.klass));
                break;
+       case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
+               target = mono_create_delegate_trampoline (patch_info->data.klass);
+               break;
        case MONO_PATCH_INFO_SFLDA: {
                MonoVTable *vtable = mono_class_vtable (domain, patch_info->data.field->parent);
                if (!vtable->initialized && !(vtable->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
@@ -10844,6 +10867,12 @@ mono_codegen (MonoCompile *cfg)
                                if (vtable) {
                                        patch_info->type = MONO_PATCH_INFO_CLASS_INIT;
                                        patch_info->data.klass = vtable->klass;
+                               } else {
+                                       MonoClass *klass = mono_find_delegate_trampoline_by_addr (patch_info->data.target);
+                                       if (klass) {
+                                               patch_info->type = MONO_PATCH_INFO_DELEGATE_TRAMPOLINE;
+                                               patch_info->data.klass = klass;
+                                       }
                                }
                        }
                        break;
@@ -12967,6 +12996,8 @@ mini_cleanup (MonoDomain *domain)
        g_hash_table_destroy (jit_icall_name_hash);
        if (class_init_hash_addr)
                g_hash_table_destroy (class_init_hash_addr);
+       if (delegate_trampoline_hash_addr)
+               g_hash_table_destroy (delegate_trampoline_hash_addr);
        g_free (emul_opcode_map);
 
        mono_arch_cleanup ();
index f2959677076346670b413b065ca24e7d61aabf62..a47429727a663af6851a7cd5e05779f6094d93a5 100644 (file)
@@ -29,4 +29,5 @@ PATCH_INFO(WRAPPER, "wrapper")
 PATCH_INFO(GOT_OFFSET, "got_offset")
 PATCH_INFO(DECLSEC, "declsec")
 PATCH_INFO(RVA, "rva")
+PATCH_INFO(DELEGATE_TRAMPOLINE, "delegate_trampoline")
 PATCH_INFO(NONE, "none")