Skip to content

Commit 3914bd8

Browse files
committed
[mono] Fix the emission of EnumEqualityComparer instances into the corlib AOT image.
Add a few dummy enums to the Mono namespace in corlib, and use them to create valid EnumEqualityComparer instances. Also make sure the instances are actually emitted and not replaced by gsharedvt instances. Fixes #49229.
1 parent 9849163 commit 3914bd8

3 files changed

Lines changed: 63 additions & 7 deletions

File tree

src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,15 @@
618618
<type fullname="Mono.ValueTuple`3" preserve="fields"/>
619619
<type fullname="Mono.ValueTuple`4" preserve="fields"/>
620620
<type fullname="Mono.ValueTuple`5" preserve="fields"/>
621+
<!-- aot-compiler.c -->
622+
<type fullname="Mono.I8Enum" preserve="fields"/>
623+
<type fullname="Mono.UI8Enum" preserve="fields"/>
624+
<type fullname="Mono.I16Enum" preserve="fields"/>
625+
<type fullname="Mono.UI16Enum" preserve="fields"/>
626+
<type fullname="Mono.I32Enum" preserve="fields"/>
627+
<type fullname="Mono.UI32Enum" preserve="fields"/>
628+
<type fullname="Mono.I64Enum" preserve="fields"/>
629+
<type fullname="Mono.UI64Enum" preserve="fields"/>
621630

622631
<type fullname="System.AppContext">
623632
<!-- appdomain.c: mono_runtime_install_appctx_properties -->

src/mono/System.Private.CoreLib/src/Mono/RuntimeStructs.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,38 @@ internal struct ValueTuple<T1, T2, T3, T4, T5>
118118
public T5 Item5;
119119
}
120120

121+
internal enum I8Enum : byte
122+
{
123+
}
124+
125+
internal enum UI8Enum : sbyte
126+
{
127+
}
128+
129+
internal enum I16Enum : short
130+
{
131+
}
132+
133+
internal enum UI16Enum : ushort
134+
{
135+
}
136+
137+
internal enum I32Enum : int
138+
{
139+
}
140+
141+
internal enum UI32Enum : uint
142+
{
143+
}
144+
145+
internal enum I64Enum : long
146+
{
147+
}
148+
149+
internal enum UI64Enum : ulong
150+
{
151+
}
152+
121153
internal class NullByRefReturnException : Exception
122154
{
123155
public NullByRefReturnException()

src/mono/mono/mini/aot-compiler.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5185,6 +5185,19 @@ is_vt_inst (MonoGenericInst *inst)
51855185
return FALSE;
51865186
}
51875187

5188+
static gboolean
5189+
is_vt_inst_no_enum (MonoGenericInst *inst)
5190+
{
5191+
int i;
5192+
5193+
for (i = 0; i < inst->type_argc; ++i) {
5194+
MonoType *t = inst->type_argv [i];
5195+
if (MONO_TYPE_ISSTRUCT (t))
5196+
return TRUE;
5197+
}
5198+
return FALSE;
5199+
}
5200+
51885201
static gboolean
51895202
method_has_type_vars (MonoMethod *method)
51905203
{
@@ -5338,7 +5351,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
53385351
* WASM only since other platforms depend on the
53395352
* previous behavior.
53405353
*/
5341-
if ((acfg->jit_opts & MONO_OPT_GSHAREDVT) && mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst && is_vt_inst (mono_class_get_generic_class (klass)->context.class_inst)) {
5354+
if ((acfg->jit_opts & MONO_OPT_GSHAREDVT) && mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst && is_vt_inst_no_enum (mono_class_get_generic_class (klass)->context.class_inst)) {
53425355
use_gsharedvt = TRUE;
53435356
use_gsharedvt_for_array = TRUE;
53445357
}
@@ -5758,17 +5771,19 @@ add_generic_instances (MonoAotCompile *acfg)
57585771

57595772
/* Add instances of EnumEqualityComparer which are created by EqualityComparer<T> for enums */
57605773
{
5761-
MonoClass *enum_comparer;
5774+
MonoClass *k, *enum_comparer;
57625775
MonoType *insts [16];
57635776
int ninsts;
5777+
const char *enum_names [] = { "I8Enum", "I16Enum", "I32Enum", "I64Enum", "UI8Enum", "UI16Enum", "UI32Enum", "UI64Enum" };
57645778

57655779
ninsts = 0;
5766-
insts [ninsts ++] = int32_type;
5767-
insts [ninsts ++] = uint32_type;
5768-
insts [ninsts ++] = uint16_type;
5769-
insts [ninsts ++] = byte_type;
5780+
for (int i = 0; i < G_N_ELEMENTS (enum_names); ++i) {
5781+
k = mono_class_try_load_from_name (acfg->image, "Mono", enum_names [i]);
5782+
g_assert (k);
5783+
insts [ninsts ++] = m_class_get_byval_arg (k);
5784+
}
57705785
enum_comparer = mono_class_load_from_name (mono_defaults.corlib, "System.Collections.Generic", "EnumEqualityComparer`1");
5771-
add_instances_of (acfg, enum_comparer, insts, ninsts, FALSE);
5786+
add_instances_of (acfg, enum_comparer, insts, ninsts, TRUE);
57725787
}
57735788

57745789
/* Add instances of the array generic interfaces for primitive types */

0 commit comments

Comments
 (0)