From ca10ab93f8495fc3f3efd81223fc94a4315000ea Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Mon, 21 Aug 2023 18:34:26 +0200 Subject: [PATCH 1/5] Extend mono_gsharedvt_constrained_call JIT icall to handle static virtual methods --- src/mono/mono/mini/jit-icalls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index 04a15e94aea16..496e849409d67 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1449,8 +1449,8 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl m = info->method; break; default: - /* Object.GetType () is an intrinsic under netcore */ - if (!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType")) { + /* Object.GetType () is an intrinsic under netcore or cmethod is static virtual methods where the receiver's type is null */ + if ((!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType")) || (m_method_is_static (cmethod) && m_method_is_virtual (cmethod))) { MonoVTable *vt; vt = mono_class_vtable_checked (klass, error); From 1cdf446e3dfc6a5b6ddaf885fcf5efcabf6ca645 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Tue, 22 Aug 2023 16:05:12 +0200 Subject: [PATCH 2/5] Handle static virtual calls in constrained_gsharedvt_call_setup --- src/mono/mono/mini/jit-icalls.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index 496e849409d67..a3b8fe9c79d77 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1358,7 +1358,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k error_init (error); - if (mono_class_is_interface (klass) || !m_class_is_valuetype (klass)) { + if ((mono_class_is_interface (klass) || !m_class_is_valuetype (klass)) && !m_method_is_static (cmethod)) { MonoObject *this_obj; is_iface = mono_class_is_interface (klass); @@ -1390,7 +1390,12 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k } } - if (m_class_is_valuetype (klass) && (m->klass == mono_defaults.object_class || m->klass == m_class_get_parent (mono_defaults.enum_class) || m->klass == mono_defaults.enum_class)) { + if (m_method_is_static (cmethod)) { + /* + * Static calls don't have this arg + */ + *this_arg = NULL; + } else if (m_class_is_valuetype (klass) && (m->klass == mono_defaults.object_class || m->klass == m_class_get_parent (mono_defaults.enum_class) || m->klass == mono_defaults.enum_class)) { /* * Calling a non-vtype method with a vtype receiver, has to box. */ @@ -1449,8 +1454,8 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl m = info->method; break; default: - /* Object.GetType () is an intrinsic under netcore or cmethod is static virtual methods where the receiver's type is null */ - if ((!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType")) || (m_method_is_static (cmethod) && m_method_is_virtual (cmethod))) { + /* Object.GetType () is an intrinsic under netcore */ + if ((!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType"))) { MonoVTable *vt; vt = mono_class_vtable_checked (klass, error); From 1b3363379dc27df953c2b31efbae428987f2ee24 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Tue, 22 Aug 2023 17:18:17 +0200 Subject: [PATCH 3/5] Fix lint --- src/mono/mono/mini/jit-icalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index a3b8fe9c79d77..628d18abe35cf 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1455,7 +1455,7 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl break; default: /* Object.GetType () is an intrinsic under netcore */ - if ((!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType"))) { + if (!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType")) { MonoVTable *vt; vt = mono_class_vtable_checked (klass, error); From ed9c4723b6bb910ceaeb0605a466667f1dee8cc8 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Tue, 22 Aug 2023 18:04:33 +0200 Subject: [PATCH 4/5] Add runtime test --- .../ConstrainedCall/static_virtual_calls.cs | 47 +++++++++++++++++++ .../static_virtual_calls.csproj | 5 ++ 2 files changed, 52 insertions(+) create mode 100644 src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs create mode 100644 src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj diff --git a/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs b/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs new file mode 100644 index 0000000000000..b2cd4d9be1dfb --- /dev/null +++ b/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +using System; +using Xunit; + + +public interface ITypeChecker +{ + static abstract bool Test(); +} + +public interface IHandler +{ + bool Test(); +} + +public class TypeChecker : ITypeChecker +{ + public static bool Test() => true; +} + +public class Handler : IHandler where TChecker : ITypeChecker +{ + public bool Test() => TChecker.Test(); +} + +public class test +{ + [Fact] + public static int TestEntryPoint() + { + var handler = GetHandler(); + bool test = handler.Test(); + if (test) { + Console.WriteLine("PASSED"); + return 100; + } + + Console.WriteLine("FAILED"); + return 101; + } + + public static IHandler GetHandler() => new Handler(); +} + diff --git a/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj b/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj new file mode 100644 index 0000000000000..197767e2c4e24 --- /dev/null +++ b/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj @@ -0,0 +1,5 @@ + + + + + From f09cd15694873d73965e256deeb9050fb97a0714 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Wed, 23 Aug 2023 23:17:03 +0200 Subject: [PATCH 5/5] Remove runtime test --- .../ConstrainedCall/static_virtual_calls.cs | 47 ------------------- .../static_virtual_calls.csproj | 5 -- 2 files changed, 52 deletions(-) delete mode 100644 src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs delete mode 100644 src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj diff --git a/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs b/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs deleted file mode 100644 index b2cd4d9be1dfb..0000000000000 --- a/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -using System; -using Xunit; - - -public interface ITypeChecker -{ - static abstract bool Test(); -} - -public interface IHandler -{ - bool Test(); -} - -public class TypeChecker : ITypeChecker -{ - public static bool Test() => true; -} - -public class Handler : IHandler where TChecker : ITypeChecker -{ - public bool Test() => TChecker.Test(); -} - -public class test -{ - [Fact] - public static int TestEntryPoint() - { - var handler = GetHandler(); - bool test = handler.Test(); - if (test) { - Console.WriteLine("PASSED"); - return 100; - } - - Console.WriteLine("FAILED"); - return 101; - } - - public static IHandler GetHandler() => new Handler(); -} - diff --git a/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj b/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj deleted file mode 100644 index 197767e2c4e24..0000000000000 --- a/src/tests/JIT/Generics/ConstrainedCall/static_virtual_calls.csproj +++ /dev/null @@ -1,5 +0,0 @@ - - - - -