[Mono-patches] r78139 - trunk/mono/mono/mini
Rodrigo Kumpera (kumpera@gmail.com)
mono-patches-list at lists.ximian.com
Tue May 29 11:46:07 EDT 2007
Author: kumpera
Date: 2007-05-29 11:46:07 -0400 (Tue, 29 May 2007)
New Revision: 78139
Added:
trunk/mono/mono/mini/devirtualization.cs
Modified:
trunk/mono/mono/mini/ChangeLog
trunk/mono/mono/mini/Makefile.am
trunk/mono/mono/mini/inssel.brg
Log:
2007-05-29 Rodrigo Kumpera <kumpera at gmail.com>
* inssel.brg (mini_emit_virtual_call): Statically dispatch virtual calls to
sealed classes or methods.
*devirtualization.cs: tests for the new optimization
Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog 2007-05-29 15:25:03 UTC (rev 78138)
+++ trunk/mono/mono/mini/ChangeLog 2007-05-29 15:46:07 UTC (rev 78139)
@@ -1,3 +1,9 @@
+2007-05-29 Rodrigo Kumpera <kumpera at gmail.com>
+
+ * inssel.brg (mini_emit_virtual_call): Statically dispatch virtual calls to
+ sealed classes or methods.
+ *devirtualization.cs: tests for the new optimization
+
2007-05-29 Zoltan Varga <vargaz at gmail.com>
* liveness.c (update_gen_kill_set): No need to set VOLATILE flags here, it is done
Modified: trunk/mono/mono/mini/Makefile.am
===================================================================
--- trunk/mono/mono/mini/Makefile.am 2007-05-29 15:25:03 UTC (rev 78138)
+++ trunk/mono/mono/mini/Makefile.am 2007-05-29 15:46:07 UTC (rev 78139)
@@ -232,6 +232,7 @@
basic-math.cs \
basic.cs \
exceptions.cs \
+ devirtualization.cs \
iltests.il.in \
test.cs
@@ -252,7 +253,7 @@
mono_debugger_sources =
endif
-regtests=basic.exe arrays.exe basic-float.exe basic-math.exe basic-long.exe objects.exe basic-calls.exe iltests.exe exceptions.exe bench.exe
+regtests=basic.exe arrays.exe basic-float.exe basic-math.exe basic-long.exe objects.exe basic-calls.exe iltests.exe exceptions.exe bench.exe devirtualization.exe
regtests2=generics.exe il2tests.exe
common_BURGSRC= $(srcdir)/inssel.brg $(srcdir)/inssel-float.brg
Added: trunk/mono/mono/mini/devirtualization.cs
===================================================================
--- trunk/mono/mono/mini/devirtualization.cs 2007-05-29 15:25:03 UTC (rev 78138)
+++ trunk/mono/mono/mini/devirtualization.cs 2007-05-29 15:46:07 UTC (rev 78139)
@@ -0,0 +1,196 @@
+using System;
+using System.Reflection;
+
+/*
+ * Regression tests for the mono JIT.
+ *
+ * Each test needs to be of the form:
+ *
+ * static int test_<result>_<name> ();
+ *
+ * where <result> is an integer (the value that needs to be returned by
+ * the method to make it pass.
+ * <name> is a user-displayed name used to identify the test.
+ *
+ * The tests can be driven in two ways:
+ * *) running the program directly: Main() uses reflection to find and invoke
+ * the test methods (this is useful mostly to check that the tests are correct)
+ * *) with the --regression switch of the jit (this is the preferred way since
+ * all the tests will be run with optimizations on and off)
+ *
+ * The reflection logic could be moved to a .dll since we need at least another
+ * regression test file written in IL code to have better control on how
+ * the IL code looks.
+ */
+
+delegate int IntNoArgs();
+
+public class Base {
+
+ public virtual int method1 () {
+ return 1;
+ }
+
+ public virtual int method2 () {
+ return 1;
+ }
+
+ public virtual int method3 () {
+ return 1;
+ }
+
+ public virtual int method4 () {
+ return 1;
+ }
+
+ public virtual int method5 () {
+ return 1;
+ }
+
+}
+
+public class Middle : Base {
+ public override int method2 () {
+ return 2;
+ }
+
+ public override int method4 () {
+ return 2;
+ }
+
+ public override sealed int method5 () {
+ return 2;
+ }
+}
+
+
+public class OpenFinal : Middle {
+ public override sealed int method4 () {
+ return 3;
+ }
+
+ static public int staticMethod() {
+ return 3;
+ }
+
+}
+
+sealed public class SealedFinal : Middle {
+ public override int method1 () {
+ return 4;
+ }
+
+ static public int staticMethod() {
+ return 4;
+ }
+}
+
+
+class Tests {
+
+ static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
+ }
+
+ static public int test_0_sealed_class_devirt_right_method () {
+ SealedFinal x = new SealedFinal ();
+ if (x.method1 () != 4)
+ return 1;
+ if (x.method2 () != 2)
+ return 2;
+ if (x.method3 () != 1)
+ return 1;
+ return 0;
+ }
+
+ static public int test_0_sealed_method_devirt_right_method () {
+ OpenFinal x = new OpenFinal ();
+ if (x.method4 () != 3)
+ return 1;
+ if (x.method5 () != 2)
+ return 2;
+ return 0;
+ }
+
+ static public int test_0_sealed_class_devirt_right_method_using_delegates () {
+ SealedFinal x = new SealedFinal ();
+ IntNoArgs d1 = new IntNoArgs(x.method1);
+ IntNoArgs d2 = new IntNoArgs(x.method2);
+ IntNoArgs d3 = new IntNoArgs(x.method3);
+
+ if (d1 () != 4)
+ return 1;
+ if (d2 () != 2)
+ return 2;
+ if (d3 () != 1)
+ return 1;
+ return 0;
+ }
+
+ static public int test_0_sealed_method_devirt_right_method_using_delegates () {
+ OpenFinal x = new OpenFinal ();
+ IntNoArgs d1 = new IntNoArgs(x.method4);
+ IntNoArgs d2 = new IntNoArgs(x.method5);
+
+ if (d1 () != 3)
+ return 1;
+ if (d2 () != 2)
+ return 2;
+ return 0;
+ }
+
+
+ static public int test_0_delegate_over_static_method_devirtualize_ok () {
+ IntNoArgs d1 = new IntNoArgs(OpenFinal.staticMethod);
+ IntNoArgs d2 = new IntNoArgs(SealedFinal.staticMethod);
+
+ if (d1 () != 3)
+ return 1;
+ if (d2 () != 4)
+ return 2;
+
+ return 0;
+ }
+
+ static public int test_0_npe_still_happens() {
+ OpenFinal x = null;
+ SealedFinal y = null;
+
+ try {
+ y.method1();
+ return 1;
+ } catch(NullReferenceException e) {
+ ;//ok
+ }
+
+ try {
+ y.method2();
+ return 2;
+ } catch(NullReferenceException e) {
+ ;//ok
+ }
+
+ try {
+ y.method3();
+ return 3;
+ } catch(NullReferenceException e) {
+ ;//ok
+ }
+
+ try {
+ x.method4();
+ return 4;
+ } catch(NullReferenceException e) {
+ ;//ok
+ }
+
+ try {
+ x.method5();
+ return 5;
+ } catch(NullReferenceException e) {
+ ;//ok
+ }
+
+ return 0;
+ }
+}
\ No newline at end of file
Modified: trunk/mono/mono/mini/inssel.brg
===================================================================
--- trunk/mono/mono/mini/inssel.brg 2007-05-29 15:25:03 UTC (rev 78138)
+++ trunk/mono/mono/mini/inssel.brg 2007-05-29 15:46:07 UTC (rev 78139)
@@ -1698,7 +1698,23 @@
mono_bblock_add_inst (cfg->cbb, tree);
return;
}
+
+ if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) &&
+ ((method->flags & METHOD_ATTRIBUTE_FINAL) ||
+ (method->klass && method->klass->flags & TYPE_ATTRIBUTE_SEALED))) {
+ /*
+ * the method is virtual, but we can statically dispatch since either
+ * it's class or the method itself are sealed.
+ * But first we need to ensure it's not a null reference.
+ */
+ MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, this_reg);
+ tree->dreg = state->reg1;
+ tree->opcode = novirtop;
+ mono_bblock_add_inst (cfg->cbb, tree);
+ return;
+ }
+
/* Initialize method->slot */
mono_class_setup_vtable (method->klass);
More information about the Mono-patches
mailing list