2008-05-22 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Thu, 22 May 2008 21:52:25 +0000 (21:52 -0000)
committerMark Probst <mark.probst@gmail.com>
Thu, 22 May 2008 21:52:25 +0000 (21:52 -0000)
* mini.c, jit-icalls.c, jit-icalls.h: Make generic sharing work
together with domain sharing.

2008-05-22  Mark Probst  <mark.probst@gmail.com>

* Makefile.am: Do generic sharing tests with domain sharing turned
on as well.

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

mono/mini/ChangeLog
mono/mini/jit-icalls.c
mono/mini/jit-icalls.h
mono/mini/mini.c
mono/tests/ChangeLog
mono/tests/Makefile.am

index be2a79081b462b706c5e534afb6cd8dfd75b535c..7733082421fdd5d185ce4896965a2aafd293bd33 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-22  Mark Probst  <mark.probst@gmail.com>
+
+       * mini.c, jit-icalls.c, jit-icalls.h: Make generic sharing work
+       together with domain sharing.
+
 2008-05-22  Mark Probst  <mark.probst@gmail.com>
 
        * mini.c: Treat callvirts to final methods like non-virtual calls
index c8ab8cf001a8f14b124f51708778d7815d02186f..42b1efe335903ca32f3ef2b95e1d461a7ba7848d 100644 (file)
@@ -685,6 +685,23 @@ mono_ldtoken_wrapper (MonoImage *image, int token, MonoGenericContext *context)
        return res;
 }
 
+gpointer
+mono_ldtoken_wrapper_generic_shared (MonoImage *image, int token, MonoMethod *method)
+{
+       MonoGenericContainer *generic_container = method->generic_container;
+       MonoMethodSignature *sig = mono_method_signature (method);
+       MonoGenericContext *generic_context;
+
+       if (sig->is_inflated) {
+               generic_context = mono_method_get_context (method);
+       } else {
+               g_assert (generic_container);
+               generic_context = &generic_container->context;
+       }
+
+       return mono_ldtoken_wrapper (image, token, generic_context);
+}
+
 guint64
 mono_fconv_u8 (double v)
 {
index ae269a649ef26e9dd900a1b89bdb332ba63d8e40..1b376f1986dd65c9d3f4fa3b8c2ef495fca8ea0e 100644 (file)
@@ -55,6 +55,8 @@ gpointer mono_class_static_field_address (MonoDomain *domain, MonoClassField *fi
 
 gpointer mono_ldtoken_wrapper (MonoImage *image, int token, MonoGenericContext *context) MONO_INTERNAL;
 
+gpointer mono_ldtoken_wrapper_generic_shared (MonoImage *image, int token, MonoMethod *method) MONO_INTERNAL;
+
 guint64 mono_fconv_u8 (double v) MONO_INTERNAL;
 
 gint64 mono_fconv_i8 (double v) MONO_INTERNAL;
index 4b2caf4a45b70a717f654356574cd9334632b294..4179c31389be2a1bcb22a1f42c02ec243c612501 100644 (file)
@@ -3119,11 +3119,12 @@ handle_alloc (MonoCompile *cfg, MonoBasicBlock *bblock, MonoClass *klass, gboole
 }
 
 static int
-handle_alloc_from_inst (MonoCompile *cfg, MonoBasicBlock *bblock, MonoClass *klass, MonoInst *vtable_inst,
+handle_alloc_from_inst (MonoCompile *cfg, MonoBasicBlock *bblock, MonoClass *klass, MonoInst *data_inst,
                gboolean for_box, const guchar *ip)
 {
        MonoInst *iargs [2];
        MonoMethod *managed_alloc = NULL;
+       void *alloc_ftn;
        /*
          FIXME: we cannot get managed_alloc here because we can't get
          the class's vtable (because it's not a closed class)
@@ -3132,17 +3133,24 @@ handle_alloc_from_inst (MonoCompile *cfg, MonoBasicBlock *bblock, MonoClass *kla
        MonoMethod *managed_alloc = mono_gc_get_managed_allocator (vtable, for_box);
        */
 
-       g_assert (!(cfg->opt & MONO_OPT_SHARED));
-       g_assert (!cfg->compile_aot);
+       if (cfg->opt & MONO_OPT_SHARED) {
+               NEW_DOMAINCONST (cfg, iargs [0]);
+               iargs [1] = data_inst;
+               alloc_ftn = mono_object_new;
+       } else {
+               g_assert (!cfg->compile_aot);
+
+               if (managed_alloc) {
+                       iargs [0] = data_inst;
+                       return mono_emit_method_call_spilled (cfg, bblock, managed_alloc,
+                               mono_method_signature (managed_alloc), iargs, ip, NULL);
+               }
 
-       if (managed_alloc) {
-               iargs [0] = vtable_inst;
-               return mono_emit_method_call_spilled (cfg, bblock, managed_alloc, mono_method_signature (managed_alloc), iargs, ip, NULL);
+               iargs [0] = data_inst;
+               alloc_ftn = mono_object_new_specific;
        }
 
-       iargs [0] = vtable_inst;
-
-       return mono_emit_jit_icall (cfg, bblock, mono_object_new_specific, iargs, ip);
+       return mono_emit_jit_icall (cfg, bblock, alloc_ftn, iargs, ip);
 }
 
 /**
@@ -3210,13 +3218,13 @@ handle_box (MonoCompile *cfg, MonoBasicBlock *bblock, MonoInst *val, const gucha
 
 static MonoInst *
 handle_box_from_inst (MonoCompile *cfg, MonoBasicBlock *bblock, MonoInst *val, const guchar *ip,
-               MonoClass *klass, MonoInst *vtable_inst)
+               MonoClass *klass, MonoInst *data_inst)
 {
        int temp;
 
        g_assert (!mono_class_is_nullable (klass));
 
-       temp = handle_alloc_from_inst (cfg, bblock, klass, vtable_inst, TRUE, ip);
+       temp = handle_alloc_from_inst (cfg, bblock, klass, data_inst, TRUE, ip);
 
        return handle_box_copy (cfg, bblock, val, ip, klass, temp);
 }
@@ -4531,6 +4539,16 @@ get_runtime_generic_context_method (MonoCompile *cfg, MonoMethod *method, MonoBa
        return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, arg_num, ip);
 }
 
+static MonoInst*
+get_runtime_generic_context_field (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *bblock,
+       MonoClassField *field, MonoGenericContext *generic_context, MonoInst *rgctx, int rgctx_type,
+       const unsigned char *ip)
+{
+       int arg_num = mono_class_lookup_or_register_other_info (method->klass, field, rgctx_type, generic_context);
+
+       return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, arg_num, ip);
+}
+
 static gboolean
 generic_class_is_reference_type (MonoCompile *cfg, MonoClass *klass)
 {
@@ -6685,18 +6703,19 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                         * will be transformed into a normal call there.
                                         */
                                } else if (generic_shared) {
-                                       MonoInst *this = NULL, *rgctx, *vtable;
-
-                                       GENERIC_SHARING_FAILURE_IF_VALUETYPE_METHOD (*ip);
+                                       MonoInst *rgctx, *data;
+                                       int rgctx_info;
 
-                                       if (!(method->flags & METHOD_ATTRIBUTE_STATIC))
-                                               NEW_ARGLOAD (cfg, this, 0);
-                                       rgctx = get_runtime_generic_context (cfg, method, this, ip);
-                                       vtable = get_runtime_generic_context_ptr (cfg, method, bblock, cmethod->klass,
+                                       GET_RGCTX (rgctx);
+                                       if (cfg->opt & MONO_OPT_SHARED)
+                                               rgctx_info = MONO_RGCTX_INFO_KLASS;
+                                       else
+                                               rgctx_info = MONO_RGCTX_INFO_VTABLE;
+                                       data = get_runtime_generic_context_ptr (cfg, method, bblock, cmethod->klass,
                                                token, MINI_TOKEN_SOURCE_METHOD, generic_context,
-                                               rgctx, MONO_RGCTX_INFO_VTABLE, ip);
+                                               rgctx, rgctx_info, ip);
 
-                                       temp = handle_alloc_from_inst (cfg, bblock, cmethod->klass, vtable, FALSE, ip);
+                                       temp = handle_alloc_from_inst (cfg, bblock, cmethod->klass, data, FALSE, ip);
                                        NEW_TEMPLOAD (cfg, *sp, temp);
                                } else {
                                        MonoVTable *vtable = mono_class_vtable (cfg->domain, cmethod->klass);
@@ -7344,7 +7363,27 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                addr = g_hash_table_lookup (cfg->domain->special_static_fields, field);
                        mono_domain_unlock (cfg->domain);
 
-                       if (shared_access) {
+                       if ((cfg->opt & MONO_OPT_SHARED) || (cfg->compile_aot && addr)) {
+                               int temp;
+                               MonoInst *iargs [2];
+                               MonoInst *domain_var;
+
+                               g_assert (field->parent);
+                               /* avoid depending on undefined C behavior in sequence points */
+                               domain_var = mono_get_domainvar (cfg);
+                               NEW_TEMPLOAD (cfg, iargs [0], domain_var->inst_c0);
+                               if (shared_access) {
+                                       MonoInst *rgctx;
+
+                                       GET_RGCTX (rgctx);
+                                       iargs [1] = get_runtime_generic_context_field (cfg, method, bblock, field,
+                                                       generic_context, rgctx, MONO_RGCTX_INFO_CLASS_FIELD, ip);
+                               } else {
+                                       NEW_FIELDCONST (cfg, iargs [1], field);
+                               }
+                               temp = mono_emit_jit_icall (cfg, bblock, mono_class_static_field_address, iargs, ip);
+                               NEW_TEMPLOAD (cfg, ins, temp);
+                       } else if (shared_access) {
                                MonoInst *this, *rgctx, *static_data;
 
                                GENERIC_SHARING_FAILURE_IF_VALUETYPE_METHOD (*ip);
@@ -7408,18 +7447,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        ins->type = STACK_PTR;
                                        ins->klass = klass;
                                }
-                       } else if ((cfg->opt & MONO_OPT_SHARED) || (cfg->compile_aot && addr)) {
-                               int temp;
-                               MonoInst *iargs [2];
-                               MonoInst *domain_var;
-                               
-                               g_assert (field->parent);
-                               /* avoid depending on undefined C behavior in sequence points */
-                               domain_var = mono_get_domainvar (cfg);
-                               NEW_TEMPLOAD (cfg, iargs [0], domain_var->inst_c0);
-                               NEW_FIELDCONST (cfg, iargs [1], field);
-                               temp = mono_emit_jit_icall (cfg, bblock, mono_class_static_field_address, iargs, ip);
-                               NEW_TEMPLOAD (cfg, ins, temp);
                        } else {
                                MonoVTable *vtable;
                                vtable = mono_class_vtable (cfg->domain, klass);
@@ -7607,7 +7634,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        break;
                case CEE_BOX: {
                        MonoInst *val;
-                       gboolean generic_shared = FALSE;
+                       int context_used = 0;
 
                        CHECK_STACK (1);
                        --sp;
@@ -7617,11 +7644,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        klass = mini_get_class (method, token, generic_context);
                        CHECK_TYPELOAD (klass);
 
-                       if (cfg->generic_sharing_context && mono_class_check_context_used (klass)) {
-                               if (mono_class_is_nullable (klass))
-                                       GENERIC_SHARING_FAILURE (CEE_BOX);
-                               else
-                                       generic_shared = TRUE;
+                       if (cfg->generic_sharing_context) {
+                               context_used = mono_class_check_context_used (klass);
+
+                               if (context_used & MONO_GENERIC_CONTEXT_USED_METHOD)
+                                       GENERIC_SHARING_FAILURE (*ip);
                        }
 
                        if (generic_class_is_reference_type (cfg, klass)) {
@@ -7670,19 +7697,26 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                start_new_bblock = 1;
                                break;
                        }
-                       if (generic_shared) {
-                               MonoInst *this = NULL, *rgctx, *vtable;
+                       if (context_used) {
+                               MonoInst *rgctx;
 
-                               GENERIC_SHARING_FAILURE_IF_VALUETYPE_METHOD (*ip);
+                               if (mono_class_is_nullable (klass)) {
+                                       GENERIC_SHARING_FAILURE (CEE_BOX);
+                               } else {
+                                       MonoInst *data;
+                                       int rgctx_info;
 
-                               if (!(method->flags & METHOD_ATTRIBUTE_STATIC))
-                                       NEW_ARGLOAD (cfg, this, 0);
-                               rgctx = get_runtime_generic_context (cfg, method, this, ip);
-                               vtable = get_runtime_generic_context_ptr (cfg, method, bblock, klass,
-                                       token, MINI_TOKEN_SOURCE_CLASS, generic_context,
-                                       rgctx, MONO_RGCTX_INFO_VTABLE, ip);
+                                       GET_RGCTX (rgctx);
+                                       if (cfg->opt & MONO_OPT_SHARED)
+                                               rgctx_info = MONO_RGCTX_INFO_KLASS;
+                                       else
+                                               rgctx_info = MONO_RGCTX_INFO_VTABLE;
+                                       data = get_runtime_generic_context_ptr (cfg, method, bblock, klass,
+                                                       token, MINI_TOKEN_SOURCE_CLASS, generic_context,
+                                                       rgctx, rgctx_info, ip);
 
-                               *sp++ = handle_box_from_inst (cfg, bblock, val, ip, klass, vtable);
+                                       *sp++ = handle_box_from_inst (cfg, bblock, val, ip, klass, data);
+                               }
                        } else {
                                *sp++ = handle_box (cfg, bblock, val, ip, klass);
                        }
@@ -8211,14 +8245,22 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                int temp;
                                MonoInst *res, *store, *addr, *vtvar, *iargs [3];
 
-                               GENERIC_SHARING_FAILURE (CEE_LDTOKEN);
-
                                vtvar = mono_compile_create_var (cfg, &handle_class->byval_arg, OP_LOCAL); 
 
                                NEW_IMAGECONST (cfg, iargs [0], image);
                                NEW_ICONST (cfg, iargs [1], n);
-                               NEW_PCONST (cfg, iargs [2], generic_context);
-                               temp = mono_emit_jit_icall (cfg, bblock, mono_ldtoken_wrapper, iargs, ip);
+                               if (cfg->generic_sharing_context) {
+                                       MonoInst *rgctx;
+
+                                       GET_RGCTX (rgctx);
+                                       iargs [2] = get_runtime_generic_context_method (cfg, method, bblock, method,
+                                                       generic_context, rgctx, MONO_RGCTX_INFO_METHOD, ip);
+                                       temp = mono_emit_jit_icall (cfg, bblock, mono_ldtoken_wrapper_generic_shared,
+                                                       iargs, ip);
+                               } else {
+                                       NEW_PCONST (cfg, iargs [2], generic_context);
+                                       temp = mono_emit_jit_icall (cfg, bblock, mono_ldtoken_wrapper, iargs, ip);
+                               }
                                NEW_TEMPLOAD (cfg, res, temp);
                                NEW_TEMPLOADA (cfg, addr, vtvar->inst_c0);
                                NEW_INDSTORE (cfg, store, addr, res, &mono_defaults.int_class->byval_arg);
@@ -13576,6 +13618,8 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_class_static_field_address , "mono_class_static_field_address", 
                                 "ptr ptr ptr", FALSE);
        register_icall (mono_ldtoken_wrapper, "mono_ldtoken_wrapper", "ptr ptr ptr ptr", FALSE);
+       register_icall (mono_ldtoken_wrapper_generic_shared, "mono_ldtoken_wrapper_generic_shared",
+               "ptr ptr ptr ptr", FALSE);
        register_icall (mono_get_special_static_data, "mono_get_special_static_data", "ptr int", FALSE);
        register_icall (mono_ldstr, "mono_ldstr", "object ptr ptr int32", FALSE);
        register_icall (mono_helper_stelem_ref_check, "helper_stelem_ref_check", "void object object", FALSE);
index 1788531bdd4df2601e30d86e3ecd6fe6af2e9e68..916e5db3b328a81cb98982801f861b067c2502c3 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-22  Mark Probst  <mark.probst@gmail.com>
+
+       * Makefile.am: Do generic sharing tests with domain sharing turned
+       on as well.
+
 2008-05-22  Mark Probst  <mark.probst@gmail.com>
 
        * generic-method-patching.2.cs: Test callvirt to sealed generic
index 7f7d1a6d1c2b2156d6880fdf811d8992b592e716..f4acc0475caddaea0ba0b4e11db3fff317f9e888 100644 (file)
@@ -700,27 +700,11 @@ test-generic-sharing : generics-sharing.2.exe shared-generic-methods.2.exe        \
                generic-interface-methods.2.exe generic-array-type.2.exe        \
                generic-method-patching.2.exe   \
                generic-null-call.2.exe
-       $(RUNTIME) -O=gshared,-inline        generics-sharing.2.exe
-       $(RUNTIME) -O=gshared,-inline        shared-generic-methods.2.exe
-       $(RUNTIME) -O=gshared,-inline        shared-generic-synchronized.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-initobj.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-box.2.exe
-       $(RUNTIME) -O=gshared,-inline        generics-sharing-other-exc.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-unbox.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-delegate.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-sizeof.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-ldobj.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-mkrefany.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-refanyval.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-ldtoken.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-ldtoken-method.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-ldtoken-field.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-virtual.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-tailcall.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-interface-methods.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-array-type.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-method-patching.2.exe
-       $(RUNTIME) -O=gshared,-inline        generic-null-call.2.exe
+       for fn in $+ ; do       \
+               echo $$fn;      \
+               $(RUNTIME) -O=gshared,-inline        $$fn;      \
+               $(RUNTIME) -O=gshared,-inline,shared $$fn;      \
+       done
 
 EXTRA_DIST += async-exceptions.cs
 async-exceptions.exe : async-exceptions.cs