Skip to content

Commit

Permalink
[mono] Fix the emission of EnumEqualityComparer instances into the co…
Browse files Browse the repository at this point in the history
…rlib 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.
  • Loading branch information
vargaz committed Mar 10, 2021
1 parent 9849163 commit 3914bd8
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,15 @@
<type fullname="Mono.ValueTuple`3" preserve="fields"/>
<type fullname="Mono.ValueTuple`4" preserve="fields"/>
<type fullname="Mono.ValueTuple`5" preserve="fields"/>
<!-- aot-compiler.c -->
<type fullname="Mono.I8Enum" preserve="fields"/>
<type fullname="Mono.UI8Enum" preserve="fields"/>
<type fullname="Mono.I16Enum" preserve="fields"/>
<type fullname="Mono.UI16Enum" preserve="fields"/>
<type fullname="Mono.I32Enum" preserve="fields"/>
<type fullname="Mono.UI32Enum" preserve="fields"/>
<type fullname="Mono.I64Enum" preserve="fields"/>
<type fullname="Mono.UI64Enum" preserve="fields"/>

<type fullname="System.AppContext">
<!-- appdomain.c: mono_runtime_install_appctx_properties -->
Expand Down
32 changes: 32 additions & 0 deletions src/mono/System.Private.CoreLib/src/Mono/RuntimeStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,38 @@ internal struct ValueTuple<T1, T2, T3, T4, T5>
public T5 Item5;
}

internal enum I8Enum : byte
{
}

internal enum UI8Enum : sbyte
{
}

internal enum I16Enum : short
{
}

internal enum UI16Enum : ushort
{
}

internal enum I32Enum : int
{
}

internal enum UI32Enum : uint
{
}

internal enum I64Enum : long
{
}

internal enum UI64Enum : ulong
{
}

internal class NullByRefReturnException : Exception
{
public NullByRefReturnException()
Expand Down
29 changes: 22 additions & 7 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -5185,6 +5185,19 @@ is_vt_inst (MonoGenericInst *inst)
return FALSE;
}

static gboolean
is_vt_inst_no_enum (MonoGenericInst *inst)
{
int i;

for (i = 0; i < inst->type_argc; ++i) {
MonoType *t = inst->type_argv [i];
if (MONO_TYPE_ISSTRUCT (t))
return TRUE;
}
return FALSE;
}

static gboolean
method_has_type_vars (MonoMethod *method)
{
Expand Down Expand Up @@ -5338,7 +5351,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
* WASM only since other platforms depend on the
* previous behavior.
*/
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)) {
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)) {
use_gsharedvt = TRUE;
use_gsharedvt_for_array = TRUE;
}
Expand Down Expand Up @@ -5758,17 +5771,19 @@ add_generic_instances (MonoAotCompile *acfg)

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

ninsts = 0;
insts [ninsts ++] = int32_type;
insts [ninsts ++] = uint32_type;
insts [ninsts ++] = uint16_type;
insts [ninsts ++] = byte_type;
for (int i = 0; i < G_N_ELEMENTS (enum_names); ++i) {
k = mono_class_try_load_from_name (acfg->image, "Mono", enum_names [i]);
g_assert (k);
insts [ninsts ++] = m_class_get_byval_arg (k);
}
enum_comparer = mono_class_load_from_name (mono_defaults.corlib, "System.Collections.Generic", "EnumEqualityComparer`1");
add_instances_of (acfg, enum_comparer, insts, ninsts, FALSE);
add_instances_of (acfg, enum_comparer, insts, ninsts, TRUE);
}

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

0 comments on commit 3914bd8

Please sign in to comment.