2008-12-14 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sun, 14 Dec 2008 09:50:57 +0000 (09:50 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 14 Dec 2008 09:50:57 +0000 (09:50 -0000)
Backport of r121496.

* liveness.c (mono_analyze_liveness): Avoid eliminating the 'this' var in
gshared code. Fixes #458947.

* generics.cs: Add a test.

svn path=/branches/mono-2-2/mono/; revision=121497

mono/mini/ChangeLog
mono/mini/generics.cs
mono/mini/liveness.c

index b133fc8a71b08edc8f708fb0b167fa498c807eb0..1ed3dda2d33e06c3db8252ef7c66cf4354cf8157 100644 (file)
@@ -1,3 +1,12 @@
+2008-12-14  Zoltan Varga  <vargaz@gmail.com>
+
+       Backport of r121496.
+       
+       * liveness.c (mono_analyze_liveness): Avoid eliminating the 'this' var in
+       gshared code. Fixes #458947.
+
+       * generics.cs: Add a test.
+
 2008-12-12  Zoltan Varga  <vargaz@gmail.com>
 
        Backport of r121457.
index 1780be65f0381ffbdf8bda2fea6246d8c6ee6ba7..d1f5b4a22c95ce8383484251b65a72dfe0d5f302 100644 (file)
@@ -383,6 +383,11 @@ class Tests {
                return the_type == typeof (string) ? 0 : 1;
        }
 
+       public static int test_0_throw_dead_this () {
+        new Foo<string> ("").throw_dead_this ();
+               return 0;
+       }
+
        public static Type the_type;
 
        public void ldvirtftn<T> () {
@@ -419,6 +424,14 @@ class Tests {
                        }
                }
 
+               public void throw_dead_this () {
+                       try {
+                               new SomeClass().ThrowAnException();
+                       }
+                       catch {
+                       }
+               }
+
                public T1 get_default () {
                        return default (T1);
                }
@@ -435,6 +448,12 @@ class Tests {
 
        }
 
+       public class SomeClass {
+               public void ThrowAnException() {
+                       throw new Exception ("Something went wrong");
+               }
+       }               
+
        public interface IMyHandler {
                object Bar<T>();
        }
index 36412f86a0f318dee5ddf73f81b08a615c10ceea..eeac7d3cecbca8e433295e7492c736cce4e1758f 100644 (file)
@@ -610,8 +610,18 @@ mono_analyze_liveness (MonoCompile *cfg)
        for (i = 0; i < max_vars; i ++) {
                MonoMethodVar *vi = MONO_VARINFO (cfg, i);
                if (cfg->varinfo [vi->idx]->opcode == OP_ARG) {
-                       if (vi->range.last_use.abs_pos == 0 && !(cfg->varinfo [vi->idx]->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)))
-                               cfg->varinfo [vi->idx]->flags |= MONO_INST_IS_DEAD;
+                       if (vi->range.last_use.abs_pos == 0 && !(cfg->varinfo [vi->idx]->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))) {
+                               /* 
+                                * Can't eliminate the this variable in gshared code, since
+                                * it is needed during exception handling to identify the
+                                * method.
+                                * It is better to check for this here instead of marking the variable
+                                * VOLATILE, since that would prevent it from being allocated to
+                                * registers.
+                                */
+                                if (!(cfg->generic_sharing_context && mono_method_signature (cfg->method)->hasthis && cfg->varinfo [vi->idx] == cfg->args [0]))
+                                        cfg->varinfo [vi->idx]->flags |= MONO_INST_IS_DEAD;
+                       }
                        vi->range.first_use.abs_pos = 0;
                }
        }