2008-08-17 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 16 Aug 2008 23:45:02 +0000 (23:45 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 16 Aug 2008 23:45:02 +0000 (23:45 -0000)
* mini.c (mono_resolve_patch_target): Handle LAZY_FETCH_TRAMPOLINE.
(mono_codegen): Ditto.

* aot-compiler.c aot-runtime.c: Ditto.

* patch-info.h: Add MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE.

* mini-trampolines.c (mono_find_rgctx_lazy_fetch_trampoline_by_addr): New
helper function to find the offset corresponding to a lazy fetch trampoline.

* mini.h (MonoCompile): Add 'orig_method' field to hold the original method
when doing generic sharing.

* aot-compiler.c: Use cfg->orig_method instead of cfg->method in a lot of
places.

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

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

index 24930438e90365b1bda8a92f2a80c770db7a3c1c..17c5f283b27de3388dd4daa15d29227d6519c461 100644 (file)
@@ -1,5 +1,24 @@
 2008-08-17  Zoltan Varga  <vargaz@gmail.com>
 
+       * mini.c (mono_resolve_patch_target): Handle LAZY_FETCH_TRAMPOLINE.
+       (mono_codegen): Ditto.
+
+       * aot-compiler.c aot-runtime.c: Ditto.
+
+       * patch-info.h: Add MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE.
+
+       * mini-trampolines.c (mono_find_rgctx_lazy_fetch_trampoline_by_addr): New
+       helper function to find the offset corresponding to a lazy fetch trampoline.
+
+       * mini.h (MonoCompile): Add 'orig_method' field to hold the original method
+       when doing generic sharing.
+
+       * aot-compiler.c: Use cfg->orig_method instead of cfg->method in a lot of
+       places.
+       
+       * mini.c (mono_create_rgctx_lazy_fetch_trampoline): Move this to
+       mini-trampolines.c to be with the other trampoline creation functions.
+
        * method-to-ir.c (mono_emit_method_call): Remove the 'signature' argument
        as it is equal to method->signature in most cases, add a 
        mono_emit_method_call_full variant which takes a signature and an imt
index e841cd18dbe674bef7d4b6f243a6684560194302..26e1943d27f7237603788c94001e40be541dff4d 100644 (file)
@@ -1870,7 +1870,8 @@ get_plt_index (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
        case MONO_PATCH_INFO_WRAPPER:
        case MONO_PATCH_INFO_INTERNAL_METHOD:
        case MONO_PATCH_INFO_JIT_ICALL_ADDR:
-       case MONO_PATCH_INFO_CLASS_INIT: {
+       case MONO_PATCH_INFO_CLASS_INIT:
+       case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE: {
                MonoJumpInfo *new_ji = mono_patch_info_dup_mp (acfg->mempool, patch_info);
                gpointer patch_id = NULL;
 
@@ -1885,6 +1886,9 @@ get_plt_index (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
                case MONO_PATCH_INFO_CLASS_INIT:
                        patch_id = patch_info->data.klass;
                        break;
+               case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+                       patch_id = GUINT_TO_POINTER (patch_info->data.offset + 1);
+                       break;
                case MONO_PATCH_INFO_WRAPPER:
                        hash = acfg->patch_to_plt_offset_wrapper [patch_info->data.method->wrapper_type];
                        if (!hash) {
@@ -2284,7 +2288,7 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg)
        int func_alignment = 16;
        MonoMethodHeader *header;
 
-       method = cfg->method;
+       method = cfg->orig_method;
        code = cfg->native_code;
        header = mono_method_get_header (method);
 
@@ -2410,6 +2414,9 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
        case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
                encode_klass_ref (acfg, patch_info->data.klass, p, &p);
                break;
+       case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+               encode_value (patch_info->data.offset, p, &p);
+               break;
        case MONO_PATCH_INFO_FIELD:
        case MONO_PATCH_INFO_SFLDA:
                if (shared) {
@@ -2531,7 +2538,7 @@ emit_method_info (MonoAotCompile *acfg, MonoCompile *cfg)
        guint8 *p, *buf;
        guint32 first_got_offset;
 
-       method = cfg->method;
+       method = cfg->orig_method;
        code = cfg->native_code;
        header = mono_method_get_header (method);
 
@@ -2630,7 +2637,7 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg)
        MonoMethodHeader *header;
        guint8 *p, *buf, *debug_info;
 
-       method = cfg->method;
+       method = cfg->orig_method;
        code = cfg->native_code;
        header = mono_method_get_header (method);
 
@@ -3111,7 +3118,7 @@ emit_trampolines (MonoAotCompile *acfg)
                method = mono_get_method (acfg->image, token, NULL);
 
                cfg = g_hash_table_lookup (acfg->method_to_cfg, method);
-               if (!cfg || !cfg->method->klass->valuetype || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL))
+               if (!cfg || !cfg->orig_method->klass->valuetype || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL))
                        continue;
 
                symbol = g_strdup_printf ("unbox_trampoline_%d", i);
@@ -3120,14 +3127,14 @@ emit_trampolines (MonoAotCompile *acfg)
                emit_global (acfg, symbol, TRUE);
                emit_label (acfg, symbol);
 
-               call_target = g_strdup_printf (".Lm_%x", get_method_index (acfg, cfg->method));
+               call_target = g_strdup_printf (".Lm_%x", get_method_index (acfg, cfg->orig_method));
 
 #if defined(__x86_64__)
                {
                        guint8 buf [32];
                        int this_reg;
 
-                       this_reg = mono_arch_get_this_arg_reg (mono_method_signature (cfg->method), cfg->generic_sharing_context, NULL);
+                       this_reg = mono_arch_get_this_arg_reg (mono_method_signature (cfg->orig_method), cfg->generic_sharing_context, NULL);
                        code = buf;
                        amd64_alu_reg_imm (code, X86_ADD, this_reg, sizeof (MonoObject));
 
@@ -3143,7 +3150,7 @@ emit_trampolines (MonoAotCompile *acfg)
 
                        code = buf;
 
-                       if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret))
+                       if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->orig_method)->ret))
                                this_pos = 1;
 
                        ARM_ADD_REG_IMM8 (code, this_pos, this_pos, sizeof (MonoObject));
@@ -3275,12 +3282,14 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
        //acfg->opts &= ~MONO_OPT_GSHARED;
 
        // FIXME: GSHARED is on by default
+#if 1
        if (TRUE || !(acfg->opts & MONO_OPT_GSHARED)) {
                if (method->is_generic || method->klass->generic_container) {
                        acfg->stats.genericcount ++;
                        return;
                }
        }
+#endif
 
        if (acfg->aot_opts.full_aot)
                mono_use_imt = FALSE;
@@ -3478,7 +3487,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
 
        acfg->cfgs [index] = cfg;
 
-       g_hash_table_insert (acfg->method_to_cfg, cfg->method, cfg);
+       g_hash_table_insert (acfg->method_to_cfg, cfg->orig_method, cfg);
 
        acfg->stats.ccount++;
 }
@@ -3705,13 +3714,13 @@ emit_wrapper_info (MonoAotCompile *acfg)
        for (i = 0; i < acfg->nmethods; ++i) {
                MonoCompile *cfg = acfg->cfgs [i];
 
-               if (!cfg || !cfg->method->wrapper_type)
+               if (!cfg || !cfg->orig_method->wrapper_type)
                        continue;
 
-               index = get_method_index (acfg, cfg->method);
+               index = get_method_index (acfg, cfg->orig_method);
 
                // FIXME: Optimize disk usage and lookup speed
-               name = mono_method_full_name (cfg->method, TRUE);
+               name = mono_method_full_name (cfg->orig_method, TRUE);
                emit_string (acfg, name);
                emit_alignment (acfg, 4);
                emit_int32 (acfg, index);
index c23626961a185b8fe2ba55c8fdac7012bc6404a1..1358c997c5172f60476b6f8d8d472097c11d5b8c 100644 (file)
@@ -1423,6 +1423,9 @@ decode_patch_info (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji,
                if (!ji->data.klass)
                        goto cleanup;
                break;
+       case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+               ji->data.offset = decode_value (p, &p);
+               break;
        case MONO_PATCH_INFO_IMAGE:
                ji->data.image = load_image (aot_module, decode_value (p, &p));
                if (!ji->data.image)
index 2af52fd9b06310d9d3672814ac37038fe3f1f416..feff30a0072db13de6546e9e7ffe6f2cb61f99b0 100644 (file)
@@ -24,6 +24,7 @@ guint8* mono_trampoline_code [MONO_TRAMPOLINE_NUM];
 static GHashTable *class_init_hash_addr = NULL;
 static GHashTable *delegate_trampoline_hash_addr = NULL;
 static GHashTable *rgctx_lazy_fetch_trampoline_hash = NULL;
+static GHashTable *rgctx_lazy_fetch_trampoline_hash_addr = NULL;
 
 #define mono_trampolines_lock() EnterCriticalSection (&trampolines_mutex)
 #define mono_trampolines_unlock() LeaveCriticalSection (&trampolines_mutex)
@@ -855,9 +856,13 @@ mono_create_rgctx_lazy_fetch_trampoline (guint32 offset)
        ptr = mono_create_ftnptr (mono_get_root_domain (), tramp);
 
        mono_trampolines_lock ();
-       if (!rgctx_lazy_fetch_trampoline_hash)
+       if (!rgctx_lazy_fetch_trampoline_hash) {
                rgctx_lazy_fetch_trampoline_hash = g_hash_table_new (NULL, NULL);
+               rgctx_lazy_fetch_trampoline_hash_addr = g_hash_table_new (NULL, NULL);
+       }
        g_hash_table_insert (rgctx_lazy_fetch_trampoline_hash, GUINT_TO_POINTER (offset), ptr);
+       g_assert (offset != -1);
+       g_hash_table_insert (rgctx_lazy_fetch_trampoline_hash_addr, ptr, GUINT_TO_POINTER (offset + 1));
        mono_trampolines_unlock ();
 
        if (!inited) {
@@ -897,3 +902,23 @@ mono_find_delegate_trampoline_by_addr (gconstpointer addr)
        mono_trampolines_unlock ();
        return res;
 }
+
+guint32
+mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr)
+{
+       int offset;
+
+       mono_trampolines_lock ();
+       if (rgctx_lazy_fetch_trampoline_hash_addr) {
+               /* We store the real offset + 1 so we can detect when the lookup fails */
+               offset = GPOINTER_TO_INT (g_hash_table_lookup (rgctx_lazy_fetch_trampoline_hash_addr, addr));
+               if (offset)
+                       offset -= 1;
+               else
+                       offset = -1;
+       } else {
+               offset = -1;
+       }
+       mono_trampolines_unlock ();
+       return offset;
+}
index 05ef37ce8fe7979b4679f23ec574775a08e38c7d..5c4117dae880f99ec3d07202323ad8def9f50122 100644 (file)
@@ -11437,6 +11437,9 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
        case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
                target = mono_create_delegate_trampoline (patch_info->data.klass);
                break;
+       case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+               target = mono_create_rgctx_lazy_fetch_trampoline (patch_info->data.offset);
+               break;
        case MONO_PATCH_INFO_SFLDA: {
                MonoVTable *vtable = mono_class_vtable (domain, patch_info->data.field->parent);
 
@@ -12743,6 +12746,12 @@ mono_codegen (MonoCompile *cfg)
                                        if (klass) {
                                                patch_info->type = MONO_PATCH_INFO_DELEGATE_TRAMPOLINE;
                                                patch_info->data.klass = klass;
+                                       } else {
+                                               int offset = mono_find_rgctx_lazy_fetch_trampoline_by_addr (patch_info->data.target);
+                                               if (offset != -1) {
+                                                       patch_info->type = MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE;
+                                                       patch_info->data.offset = offset;
+                                               }
                                        }
                                }
                        }
@@ -13068,6 +13077,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        cfg->verbose_level = mini_verbose;
        cfg->compile_aot = compile_aot;
        cfg->skip_visibility = method->skip_visibility;
+       cfg->orig_method = method;
        if (try_generic_shared)
                cfg->generic_sharing_context = (MonoGenericSharingContext*)&cfg->generic_sharing_context;
        cfg->token_info_hash = g_hash_table_new (NULL, NULL);
index b9810b615ebe60e525a96b7332a45f23c3da5e9e..0eb6c7d25749c83d79f7028ee9dfe0083b6ce713 100644 (file)
@@ -903,6 +903,12 @@ typedef struct {
 
        /* Size of above array */
        guint32 vreg_to_inst_len;
+
+       /* 
+        * The original method to compile, differs from 'method' when doing generic
+        * sharing.
+        */
+       MonoMethod *orig_method;
 } MonoCompile;
 
 typedef enum {
@@ -1258,7 +1264,6 @@ void      mono_destroy_compile              (MonoCompile *cfg) MONO_INTERNAL;
 MonoJitICallInfo *mono_find_jit_opcode_emulation (int opcode) MONO_INTERNAL;
 void     mono_print_ins_index (int i, MonoInst *ins) MONO_INTERNAL;
 void     mono_print_ins (MonoInst *ins) MONO_INTERNAL;
-gpointer  mini_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
 gboolean  mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
 gboolean  mini_method_verify (MonoCompile *cfg, MonoMethod *method) MONO_INTERNAL;
 
@@ -1332,6 +1337,7 @@ gpointer          mono_create_delegate_trampoline (MonoClass *klass) MONO_INTERN
 gpointer          mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 MonoClass*        mono_find_delegate_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
+guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 gpointer          mono_magic_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_delegate_trampoline (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_aot_trampoline (gssize *regs, guint8 *code, guint8 *token_info, 
index 53f69607f9ebb01ef3715a23840617d1f94bfbcc..4fb0d8814f7079707a9ba8eca0bf21349d74c8a5 100644 (file)
@@ -34,4 +34,5 @@ PATCH_INFO(ICALL_ADDR, "icall_addr")
 PATCH_INFO(JIT_ICALL_ADDR, "jit_icall_addr")
 PATCH_INFO(INTERRUPTION_REQUEST_FLAG, "interruption_request_flag")
 PATCH_INFO(METHOD_RGCTX, "method_rgctx")
+PATCH_INFO(RGCTX_LAZY_FETCH_TRAMPOLINE, "rgctx_lazy_fetch_trampoline")
 PATCH_INFO(NONE, "none")