Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kyte <alexander.kyte@xamarin.com>2015-04-01 00:18:40 +0300
committerDuncan Mak <duncan.mak@xamarin.com>2015-05-27 00:14:56 +0300
commit7cec9613b4cc2abb10be61c1279606ee8d070669 (patch)
tree6bbfcff8a45e28f3001130e19470e54c71867178
parentd136b7923f60ef59bced6fad1c9a6c0c3b8c616a (diff)
[runtime] Don't set flag to skip future initialization on half-baked classeshotfix-29639
-rw-r--r--mono/metadata/class.c8
-rw-r--r--mono/tests/Makefile.am1
-rw-r--r--mono/tests/dynamic-generic-size.cs61
3 files changed, 69 insertions, 1 deletions
diff --git a/mono/metadata/class.c b/mono/metadata/class.c
index b70897dccb0..1296ed12123 100644
--- a/mono/metadata/class.c
+++ b/mono/metadata/class.c
@@ -6049,7 +6049,13 @@ mono_generic_class_get_class (MonoGenericClass *gclass)
mono_generic_class_setup_parent (klass, gklass);
if (gclass->is_dynamic) {
- klass->inited = 1;
+ /*
+ * We don't need to do any init workf with unbaked typebuilders. Generic instances created at this point will be later unregistered and/or fixed.
+ * This is to avoid work that would probably give wrong results as fields change as we build the TypeBuilder.
+ * See remove_instantiations_of_and_ensure_contents in reflection.c and its usage in reflection.c to understand the fixup stage of SRE banking.
+ */
+ if (!gklass->wastypebuilder)
+ klass->inited = 1;
mono_class_setup_supertypes (klass);
diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am
index 6a1a76a8fd2..8b0ab538b69 100644
--- a/mono/tests/Makefile.am
+++ b/mono/tests/Makefile.am
@@ -307,6 +307,7 @@ BASE_TEST_CS_SRC= \
generic-typedef.2.cs \
generic-marshalbyref.2.cs \
generic-xdomain.2.cs \
+ dynamic-generic-size.cs \
bug-431413.2.cs \
bug-459285.2.cs \
generic-virtual-invoke.2.cs \
diff --git a/mono/tests/dynamic-generic-size.cs b/mono/tests/dynamic-generic-size.cs
new file mode 100644
index 00000000000..3a26f728d10
--- /dev/null
+++ b/mono/tests/dynamic-generic-size.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Threading;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections.Generic;
+
+namespace GenericSize
+{
+ class GenericSize
+ {
+ static int Iterations = 10000;
+ static AssemblyBuilder assembly;
+ static ModuleBuilder module;
+ static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
+
+ static void SetUp ()
+ {
+ AssemblyName assemblyName = new AssemblyName ();
+ assemblyName.Name = ASSEMBLY_NAME;
+
+ assembly =
+ Thread.GetDomain ().DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Run);
+
+ module = assembly.DefineDynamicModule ("module1");
+ }
+
+ static int Main()
+ {
+ SetUp ();
+
+ TypeBuilder tb = module.DefineType ("Test", TypeAttributes.Public);
+ tb.DefineGenericParameters ("T");
+ var tb_ctor = tb.DefineDefaultConstructor (MethodAttributes.Public);
+
+ var tb2 = module.DefineType ("Test2", TypeAttributes.Public);
+ var g0 = tb2.DefineGenericParameters ("T");
+
+ var mb = tb2.DefineMethod ("Foo", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type [0]);
+
+ var il = mb.GetILGenerator();
+ il.Emit(OpCodes.Newobj, TypeBuilder.GetConstructor (tb.MakeGenericType (g0), tb_ctor));
+ il.Emit(OpCodes.Ret);
+
+ var t1 = tb.CreateType ();
+ var t2 = tb2.CreateType ();
+
+ var ginst = t2.MakeGenericType (typeof (string));
+ var method = ginst.GetMethod ("Foo", BindingFlags.Public | BindingFlags.Static);
+
+ var lst = new List<Object>();
+
+ for (int i = 0; i < GenericSize.Iterations; i++) {
+ lst.Add (method.Invoke (null, null));
+ if (i % 15 == 0)
+ GC.Collect();
+ }
+
+ return 0;
+ }
+ }
+}