Skip to content

Commit e9cd01a

Browse files
authored
[mono][aot] Allow valuetype sharing in wrappers for valuetypes with an explicit layout if the explicit size matches the computed size. (dotnet#96230)
This happens for Vector64<T>/Vector128<T>.
1 parent 1791abd commit e9cd01a

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

src/mono/mono/mini/mini-generic-sharing.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,8 +1187,30 @@ get_wrapper_shared_vtype (MonoType *t)
11871187
if (mono_class_has_failure (klass))
11881188
return NULL;
11891189

1190-
if (m_class_get_type_token (klass) && mono_metadata_packing_from_typedef (m_class_get_image (klass), m_class_get_type_token (klass), NULL, NULL))
1191-
return NULL;
1190+
guint32 packing, packing_size;
1191+
gboolean has_explicit_size = FALSE;
1192+
if (m_class_get_type_token (klass) && mono_metadata_packing_from_typedef (m_class_get_image (klass), m_class_get_type_token (klass), &packing, &packing_size)) {
1193+
// FIXME: Support other sizes
1194+
if (packing == 0 && (packing_size == 8 || packing_size == 16)) {
1195+
has_explicit_size = TRUE;
1196+
switch (packing_size) {
1197+
case 8:
1198+
findex = 1;
1199+
args [0] = m_class_get_byval_arg (mono_get_int64_class ());
1200+
break;
1201+
case 16:
1202+
findex = 2;
1203+
args [0] = m_class_get_byval_arg (mono_get_int64_class ());
1204+
args [1] = m_class_get_byval_arg (mono_get_int64_class ());
1205+
break;
1206+
default:
1207+
g_assert_not_reached ();
1208+
break;
1209+
}
1210+
} else {
1211+
return NULL;
1212+
}
1213+
}
11921214

11931215
gpointer iter = NULL;
11941216
MonoClassField *field;
@@ -1199,20 +1221,21 @@ get_wrapper_shared_vtype (MonoType *t)
11991221
if (m_class_is_byreflike (mono_class_from_mono_type_internal (ftype)))
12001222
/* Cannot inflate generic params with byreflike types */
12011223
return NULL;
1202-
args [findex ++] = ftype;
1203-
if (findex >= 16)
1204-
break;
1224+
if (!has_explicit_size) {
1225+
args [findex ++] = ftype;
1226+
if (findex >= 16)
1227+
break;
1228+
}
12051229
#ifdef TARGET_WASM
12061230
if (ftype->type == MONO_TYPE_R4 || ftype->type == MONO_TYPE_R8 || MONO_TYPE_ISSTRUCT (ftype))
12071231
has_fp = TRUE;
12081232
#endif
12091233
}
12101234

12111235
#ifdef TARGET_WASM
1212-
if (!has_fp) {
1236+
if (!has_explicit_size && !has_fp) {
12131237
guint32 align;
12141238
int size = mono_class_value_size (klass, &align);
1215-
12161239
/* Other platforms might pass small valuetypes or valuetypes with non-int fields differently */
12171240
if (align == 4 && size <= 4 * 5) {
12181241
findex = size / align;

0 commit comments

Comments
 (0)