From bb3ae37d71a0993a09abc59a0d8255c074dc885b Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 16 Nov 2018 15:15:35 -0500 Subject: [interp] attempt to intrinsify again after a method is resolved regarding generics (#11715) [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 --- mono/mini/builtin-types.cs | 32 ++++++++++++++++++++++++++++++++ mono/mini/interp/transform.c | 7 +++++++ 2 files changed, 39 insertions(+) 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 : EqualityComparer where T : IEquatable + { + 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 cmp = new MyGenericEqualityComparer (); + 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); -- cgit v1.2.3