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:
authormonojenkins <jo.shields+jenkins@xamarin.com>2018-11-16 23:15:35 +0300
committerGitHub <noreply@github.com>2018-11-16 23:15:35 +0300
commitbb3ae37d71a0993a09abc59a0d8255c074dc885b (patch)
treee3501779a83776295b96d2c28863f9ef8a3f35e3
parent78eb5303e85fd3d3482dc8ae341a43a71f9a14d6 (diff)
[interp] attempt to intrinsify again after a method is resolved regarding generics (#11715)mono-5.16.0.220
[2018-06] [interp] attempt to intrinsify again after a method is resolved regarding generics discovered when running https://github.com/Clancey/gMusic Backport of #11712. /cc @luhenry @lewurm
-rw-r--r--mono/mini/builtin-types.cs32
-rw-r--r--mono/mini/interp/transform.c7
2 files changed, 39 insertions, 0 deletions
diff --git a/mono/mini/builtin-types.cs b/mono/mini/builtin-types.cs
index 42131a766a8..a07f477a431 100644
--- a/mono/mini/builtin-types.cs
+++ b/mono/mini/builtin-types.cs
@@ -12,6 +12,7 @@ using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Collections.Generic;
public class BuiltinTests {
@@ -290,6 +291,37 @@ public class BuiltinTests {
return 0;
}
+ private sealed class MyGenericEqualityComparer<T> : EqualityComparer<T> where T : IEquatable<T>
+ {
+ public sealed override bool Equals(T x, T y) {
+ if (x != null) {
+ if (y != null)
+ return x.Equals (y);
+ return false;
+ }
+ if (y != null)
+ return false;
+ return true;
+ }
+
+ public sealed override int GetHashCode(T obj)
+ {
+ if (obj == null)
+ return 0;
+ return obj.GetHashCode ();
+ }
+ }
+
+ static int test_0_nint_genequals ()
+ {
+ MyGenericEqualityComparer<nint> cmp = new MyGenericEqualityComparer<nint> ();
+ if (cmp.Equals ((nint) 1, (nint) 2))
+ return 1;
+ if (!cmp.Equals ((nint) 4, (nint) 4))
+ return 2;
+ return 0;
+ }
+
static int test_0_nint_call_boxed_funs ()
{
object x = new nint (10);
diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c
index 0a5e3910b71..cc87a40890c 100644
--- a/mono/mini/interp/transform.c
+++ b/mono/mini/interp/transform.c
@@ -1076,6 +1076,9 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoMeth
} else if (!strcmp ("ToString", tm)) {
/* white list */
return FALSE;
+ } else if (!strcmp ("GetHashCode", tm)) {
+ /* white list */
+ return FALSE;
} else if (!strcmp ("IsNaN", tm) || !strcmp ("IsInfinity", tm) || !strcmp ("IsNegativeInfinity", tm) || !strcmp ("IsPositiveInfinity", tm)) {
g_assert (type_index == 2); // nfloat only
/* white list */
@@ -1286,6 +1289,10 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
#if DEBUG_INTERP
g_print (" : %s::%s. %s (%p)\n", target_method->klass->name, target_method->name, mono_signature_full_name (target_method->signature), target_method);
#endif
+ /* Intrinsics: Try again, it could be that `mono_get_method_constrained_with_method` resolves to a method that we can substitute */
+ if (target_method && interp_handle_intrinsics (td, target_method, csignature, readonly, &op))
+ return;
+
return_if_nok (error);
mono_class_setup_vtable (target_method->klass);