From a16f9d7534f00f8a5567909485702dd440998c95 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 22 Aug 2025 16:28:48 +0200 Subject: [PATCH 1/7] - stop validating generic constraints for classes created for AOT wrappers - next field MonoClass->skip_generic_constraints --- src/mono/mono/metadata/class-accessors.c | 19 +++++++++++++++++++ src/mono/mono/metadata/class-init.c | 12 +++++++----- src/mono/mono/metadata/class-internals.h | 3 +++ .../mono/metadata/class-private-definition.h | 1 + 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/metadata/class-accessors.c b/src/mono/mono/metadata/class-accessors.c index c71a5073fafe7f..3ada89ea8c9f2f 100644 --- a/src/mono/mono/metadata/class-accessors.c +++ b/src/mono/mono/metadata/class-accessors.c @@ -569,6 +569,25 @@ mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error) return TRUE; } +/** + * mono_class_skip_generic_constraints: + * \param klass class in which should not validate generic constraints + * + * LOCKING: Acquires the loader lock. + */ +gboolean +mono_class_skip_generic_constraints (MonoClass *klass) +{ + if (klass->skip_generic_constraints) + return FALSE; + + mono_loader_lock (); + klass->skip_generic_constraints = 1; + mono_loader_unlock (); + + return TRUE; +} + /** * mono_class_set_deferred_failure: * \param klass class in which the failure was detected diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index 52f108fc7cc9a0..acdd4404c5272a 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -2613,10 +2613,12 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ case MONO_TYPE_TYPEDBYREF: case MONO_TYPE_VALUETYPE: case MONO_TYPE_GENERICINST: - field_class = mono_class_from_mono_type_internal (field->type); - if (mono_class_is_ginst (field_class) && !mono_verifier_class_is_valid_generic_instantiation (field_class)) { - mono_class_set_type_load_failure (klass, "Field '%s' is an invalid generic instantiation of type %s", field->name, mono_type_get_full_name (field_class)); - return; + if (!klass->skip_generic_constraints) { + field_class = mono_class_from_mono_type_internal (field->type); + if (mono_class_is_ginst (field_class) && !mono_verifier_class_is_valid_generic_instantiation (field_class)) { + mono_class_set_type_load_failure (klass, "Field '%s' is an invalid generic instantiation of type %s", field->name, mono_type_get_full_name (field_class)); + return; + } } break; default: @@ -3202,7 +3204,7 @@ mono_class_init_internal (MonoClass *klass) mono_class_setup_interface_offsets_internal (klass, first_iface_slot, MONO_SETUP_ITF_OFFSETS_OVERWRITE); - if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) + if (!klass->skip_generic_constraints && mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) mono_class_set_type_load_failure (klass, "Invalid generic instantiation"); goto leave; diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index ba56a62ad6b818..310f4119bfeba1 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1418,6 +1418,9 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error); gboolean mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error); +gboolean +mono_class_skip_generic_constraints (MonoClass *klass); + void mono_class_set_deferred_failure (MonoClass *klass); diff --git a/src/mono/mono/metadata/class-private-definition.h b/src/mono/mono/metadata/class-private-definition.h index 005cd05935067e..b8c66cdb7a97f3 100644 --- a/src/mono/mono/metadata/class-private-definition.h +++ b/src/mono/mono/metadata/class-private-definition.h @@ -81,6 +81,7 @@ struct _MonoClass { /* next byte*/ guint is_exception_class : 1; /* is System.Exception or derived from it */ guint variant_search_table_inited : 1; + guint skip_generic_constraints : 1; /* type created for AOT wrapper methods, which don't need to comply with generic constraints */ MonoClass *parent; MonoClass *nested_in; From 5887daa652cd94f46edfcef9f36d9efb92778174 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Sat, 23 Aug 2025 16:51:27 +0200 Subject: [PATCH 2/7] fix --- src/mono/mono/mini/mini-generic-sharing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 11df39a80f664c..dea185d920331d 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1321,7 +1321,7 @@ get_wrapper_shared_vtype (MonoType *t) } /* - * get_wrapper_shared_type: + * get_wrapper_shared_type_full: * * Return a type which is handled identically wrt to calling conventions as T. */ @@ -1415,6 +1415,8 @@ get_wrapper_shared_type_full (MonoType *t, gboolean is_field) mono_error_assert_ok (error); /* FIXME don't swallow the error */ g_assert (klass); + mono_class_skip_generic_constraints (klass); + t = m_class_get_byval_arg (klass); MonoType *shared_type = get_wrapper_shared_vtype (t); if (shared_type) From bf2748f43b0f4455ff6461901a16feef27a6e2ae Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 27 Aug 2025 14:37:22 +0200 Subject: [PATCH 3/7] test --- .../tests/System.Text.Json.Tests/ILLink.Descriptors.xml | 1 + .../System.Text.Json.Tests/System.Text.Json.Tests.csproj | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml index 2c692431c3ac27..66c017319d43bc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml @@ -3,6 +3,7 @@ + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index f69d73da47c723..85df72c907349e 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -24,8 +24,14 @@ $(Features.Replace('nullablePublicOnly', '')) + + + + + 1 + true From 5e3e42eb1eeac348234ce8b3f8915a7059001801 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 27 Aug 2025 17:32:11 +0200 Subject: [PATCH 4/7] active issue https://github.com/dotnet/runtime/issues/119143 --- .../tests/Common/NumberHandlingTests.cs | 10 +++++++--- .../System.Text.Json.Tests/ILLink.Descriptors.xml | 1 + .../System.Text.Json.Tests.csproj | 5 ----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs b/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs index 9d02372926acd0..0b3e7529f4ca70 100644 --- a/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs @@ -404,9 +404,13 @@ public async Task Number_AsCollectionElement_RoundTrip() await RunAsCollectionElementTest(JsonNumberTestData.NullableDoubles); await RunAsCollectionElementTest(JsonNumberTestData.NullableDecimals); #if NET - await RunAsCollectionElementTest(JsonNumberTestData.NullableInt128s); - await RunAsCollectionElementTest(JsonNumberTestData.NullableUInt128s); - await RunAsCollectionElementTest(JsonNumberTestData.NullableHalfs); + // https://github.com/dotnet/runtime/issues/119143 + if (!PlatformDetection.IsBrowser) + { + await RunAsCollectionElementTest(JsonNumberTestData.NullableInt128s); + await RunAsCollectionElementTest(JsonNumberTestData.NullableUInt128s); + await RunAsCollectionElementTest(JsonNumberTestData.NullableHalfs); + } #endif } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml index 66c017319d43bc..1842a29b1b00c3 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/ILLink.Descriptors.xml @@ -4,6 +4,7 @@ + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index 85df72c907349e..530620846c553b 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -24,11 +24,6 @@ $(Features.Replace('nullablePublicOnly', '')) - - - - - 1 true From 176e0482042c186536cd0efcf38ba4eb9444fc67 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 28 Aug 2025 09:26:14 +0200 Subject: [PATCH 5/7] Update src/mono/mono/metadata/class-accessors.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/mono/mono/metadata/class-accessors.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/class-accessors.c b/src/mono/mono/metadata/class-accessors.c index 3ada89ea8c9f2f..2ff9c40ac8977a 100644 --- a/src/mono/mono/metadata/class-accessors.c +++ b/src/mono/mono/metadata/class-accessors.c @@ -570,8 +570,7 @@ mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error) } /** - * mono_class_skip_generic_constraints: - * \param klass class in which should not validate generic constraints + * \param klass class that should not validate generic constraints * * LOCKING: Acquires the loader lock. */ From 6dafdd8311f712baabf0bd3027b2fcd6343ec8fd Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 28 Aug 2025 09:49:32 +0200 Subject: [PATCH 6/7] feedback --- src/mono/mono/metadata/class-accessors.c | 9 ++++----- src/mono/mono/metadata/class-internals.h | 2 +- src/mono/mono/mini/mini-generic-sharing.c | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/metadata/class-accessors.c b/src/mono/mono/metadata/class-accessors.c index 2ff9c40ac8977a..1a64e859399228 100644 --- a/src/mono/mono/metadata/class-accessors.c +++ b/src/mono/mono/metadata/class-accessors.c @@ -570,21 +570,20 @@ mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error) } /** + * mono_class_set_skip_generic_constraints: * \param klass class that should not validate generic constraints * * LOCKING: Acquires the loader lock. */ -gboolean -mono_class_skip_generic_constraints (MonoClass *klass) +void +mono_class_set_skip_generic_constraints (MonoClass *klass) { if (klass->skip_generic_constraints) - return FALSE; + return; mono_loader_lock (); klass->skip_generic_constraints = 1; mono_loader_unlock (); - - return TRUE; } /** diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 310f4119bfeba1..5d37e88005518d 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1419,7 +1419,7 @@ gboolean mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error); gboolean -mono_class_skip_generic_constraints (MonoClass *klass); +mono_class_set_skip_generic_constraints (MonoClass *klass); void mono_class_set_deferred_failure (MonoClass *klass); diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index dea185d920331d..8ae3d2cc42006e 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1415,7 +1415,7 @@ get_wrapper_shared_type_full (MonoType *t, gboolean is_field) mono_error_assert_ok (error); /* FIXME don't swallow the error */ g_assert (klass); - mono_class_skip_generic_constraints (klass); + mono_class_set_skip_generic_constraints (klass); t = m_class_get_byval_arg (klass); MonoType *shared_type = get_wrapper_shared_vtype (t); From ff150b9bfeac6e5c6753841eab759a939d3ac85d Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 28 Aug 2025 10:15:38 +0200 Subject: [PATCH 7/7] fix --- src/mono/mono/metadata/class-internals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 5d37e88005518d..9c2c74161b9d34 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1418,7 +1418,7 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error); gboolean mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error); -gboolean +void mono_class_set_skip_generic_constraints (MonoClass *klass); void