2009-03-05 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Thu, 5 Mar 2009 20:16:59 +0000 (20:16 -0000)
committerMark Probst <mark.probst@gmail.com>
Thu, 5 Mar 2009 20:16:59 +0000 (20:16 -0000)
* method-to-ir.c (mono_method_to_ir): Only force the vtable var
for methods which actually have one.  For all other methods, make
sure the this argument var is live the whole method.

* mini.c (mini_method_compile): Every shared method has a
this/vtable/mrgctx info.  Fixes #480807.

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

mono/mini/ChangeLog
mono/mini/method-to-ir.c
mono/mini/mini.c

index d591cabf23c416684d1f073042f664a84de91af7..50eeb0595a92d481da15fbde141afdd3776de136 100644 (file)
@@ -1,3 +1,12 @@
+2009-03-05  Mark Probst  <mark.probst@gmail.com>
+
+       * method-to-ir.c (mono_method_to_ir): Only force the vtable var
+       for methods which actually have one.  For all other methods, make
+       sure the this argument var is live the whole method.
+
+       * mini.c (mini_method_compile): Every shared method has a
+       this/vtable/mrgctx info.  Fixes #480807.
+
 2009-03-05  Mark Probst  <mark.probst@gmail.com>
 
        * mini-ppc.c (mono_arch_build_imt_thunk): Add support for mixed
index 729714c86b93bb7b3c4ff7bd1f6bab2809710cf2..afd24b4eb0de9ce2399c53a83f0ba9cec1639369 100644 (file)
@@ -5467,8 +5467,18 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
        /* We force the vtable variable here for all shared methods
           for the possibility that they might show up in a stack
           trace where their exact instantiation is needed. */
-       if (cfg->generic_sharing_context)
-               mono_get_vtable_var (cfg);
+       if (cfg->generic_sharing_context && method == cfg->method) {
+               if ((method->flags & METHOD_ATTRIBUTE_STATIC) ||
+                               mini_method_get_context (method)->method_inst ||
+                               method->klass->valuetype) {
+                       mono_get_vtable_var (cfg);
+               } else {
+                       /* FIXME: Is there a better way to do this?
+                          We need the variable live for the duration
+                          of the whole method. */
+                       cfg->args [0]->flags |= MONO_INST_INDIRECT;
+               }
+       }
 
        /* add a check for this != NULL to inlined methods */
        if (is_virtual_call) {
index 4dafd3844fa0598dffbbfe11e475da2e1e13a380..749e482c9882e09f5e308b91261ccfe0060e2503 100644 (file)
@@ -3571,48 +3571,38 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 
                gi->generic_sharing_context = cfg->generic_sharing_context;
 
-               /*
-                * Non-generic static methods only get a "this" info
-                * if they use the rgctx variable (which they are
-                * forced to if they have any open catch clauses).
-                */
-               if (cfg->rgctx_var ||
-                               (!(method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) &&
-                               !mini_method_get_context (method_to_compile)->method_inst &&
-                               !method_to_compile->klass->valuetype)) {
-                       gi->has_this = 1;
-
-                       if ((method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) ||
-                                       mini_method_get_context (method_to_compile)->method_inst ||
-                                       method_to_compile->klass->valuetype) {
-                               inst = cfg->rgctx_var;
-                               g_assert (inst->opcode == OP_REGOFFSET);
-                       } else {
-                               inst = cfg->args [0];
-                       }
+               if ((method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) ||
+                               mini_method_get_context (method_to_compile)->method_inst ||
+                               method_to_compile->klass->valuetype) {
+                       g_assert (cfg->rgctx_var);
+               }
 
-                       if (inst->opcode == OP_REGVAR) {
-                               gi->this_in_reg = 1;
-                               gi->this_reg = inst->dreg;
+               gi->has_this = 1;
 
-                               //g_print ("this in reg %d\n", inst->dreg);
-                       } else {
-                               g_assert (inst->opcode == OP_REGOFFSET);
+               if ((method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) ||
+                               mini_method_get_context (method_to_compile)->method_inst ||
+                               method_to_compile->klass->valuetype) {
+                       inst = cfg->rgctx_var;
+                       g_assert (inst->opcode == OP_REGOFFSET);
+               } else {
+                       inst = cfg->args [0];
+               }
+
+               if (inst->opcode == OP_REGVAR) {
+                       gi->this_in_reg = 1;
+                       gi->this_reg = inst->dreg;
+               } else {
+                       g_assert (inst->opcode == OP_REGOFFSET);
 #ifdef __i386__
-                               g_assert (inst->inst_basereg == X86_EBP);
+                       g_assert (inst->inst_basereg == X86_EBP);
 #elif defined(__x86_64__)
-                               g_assert (inst->inst_basereg == X86_EBP || inst->inst_basereg == X86_ESP);
+                       g_assert (inst->inst_basereg == X86_EBP || inst->inst_basereg == X86_ESP);
 #endif
-                               g_assert (inst->inst_offset >= G_MININT32 && inst->inst_offset <= G_MAXINT32);
+                       g_assert (inst->inst_offset >= G_MININT32 && inst->inst_offset <= G_MAXINT32);
 
-                               gi->this_in_reg = 0;
-                               gi->this_reg = inst->inst_basereg;
-                               gi->this_offset = inst->inst_offset;
-
-                               //g_print ("this at offset %d from reg %d\n", gi->this_offset, gi->this_reg);
-                       }
-               } else {
-                       gi->has_this = 0;
+                       gi->this_in_reg = 0;
+                       gi->this_reg = inst->inst_basereg;
+                       gi->this_offset = inst->inst_offset;
                }
        }