Skip to content

Commit 4723e0d

Browse files
committed
[mono][aot] Fix the adding of generic instances referenced by gshared methods.
These methods store their data in a MONO_PATCH_INFO_GSHARED_METHOD_INFO which was not handled properly.
1 parent f7cba48 commit 4723e0d

File tree

1 file changed

+101
-61
lines changed

1 file changed

+101
-61
lines changed

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

Lines changed: 101 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8871,6 +8871,105 @@ add_gsharedvt_wrappers (MonoAotCompile *acfg, MonoMethodSignature *sig, gboolean
88718871
#endif
88728872
}
88738873

8874+
static void
8875+
add_referenced_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, int depth)
8876+
{
8877+
switch (patch_info->type) {
8878+
case MONO_PATCH_INFO_RGCTX_FETCH:
8879+
case MONO_PATCH_INFO_RGCTX_SLOT_INDEX:
8880+
case MONO_PATCH_INFO_METHOD:
8881+
case MONO_PATCH_INFO_METHOD_FTNDESC:
8882+
case MONO_PATCH_INFO_METHOD_RGCTX: {
8883+
MonoMethod *m = NULL;
8884+
8885+
if (patch_info->type == MONO_PATCH_INFO_RGCTX_FETCH || patch_info->type == MONO_PATCH_INFO_RGCTX_SLOT_INDEX) {
8886+
MonoJumpInfoRgctxEntry *e = patch_info->data.rgctx_entry;
8887+
8888+
if (e->info_type == MONO_RGCTX_INFO_GENERIC_METHOD_CODE || e->info_type == MONO_RGCTX_INFO_METHOD_FTNDESC)
8889+
m = e->data->data.method;
8890+
} else {
8891+
m = patch_info->data.method;
8892+
}
8893+
8894+
if (!m)
8895+
break;
8896+
8897+
if (m->is_inflated && (mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts))) {
8898+
if (!(mono_class_generic_sharing_enabled (m->klass) &&
8899+
mono_method_is_generic_sharable_full (m, FALSE, FALSE, FALSE)) &&
8900+
(!method_has_type_vars (m) || mono_method_is_generic_sharable_full (m, TRUE, TRUE, FALSE))) {
8901+
if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
8902+
if (mono_aot_mode_is_full (&acfg->aot_opts) && !method_has_type_vars (m))
8903+
add_extra_method_with_depth (acfg, mono_marshal_get_native_wrapper (m, TRUE, TRUE), depth + 1);
8904+
} else {
8905+
add_extra_method_with_depth (acfg, m, depth + 1);
8906+
add_types_from_method_header (acfg, m);
8907+
}
8908+
}
8909+
add_generic_class_with_depth (acfg, m->klass, depth + 5, "method");
8910+
}
8911+
if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) {
8912+
WrapperInfo *info = mono_marshal_get_wrapper_info (m);
8913+
8914+
if (info && info->subtype == WRAPPER_SUBTYPE_ELEMENT_ADDR)
8915+
add_extra_method_with_depth (acfg, m, depth + 1);
8916+
}
8917+
break;
8918+
}
8919+
case MONO_PATCH_INFO_VTABLE: {
8920+
MonoClass *klass = patch_info->data.klass;
8921+
8922+
if (mono_class_is_ginst (klass) && !mini_class_is_generic_sharable (klass))
8923+
add_generic_class_with_depth (acfg, klass, depth + 5, "vtable");
8924+
break;
8925+
}
8926+
case MONO_PATCH_INFO_SFLDA: {
8927+
MonoClass *klass = m_field_get_parent (patch_info->data.field);
8928+
8929+
/* The .cctor needs to run at runtime. */
8930+
if (mono_class_is_ginst (klass) && !mono_generic_context_is_sharable_full (&mono_class_get_generic_class (klass)->context, FALSE, FALSE) && mono_class_get_cctor (klass))
8931+
add_extra_method_with_depth (acfg, mono_class_get_cctor (klass), depth + 1);
8932+
break;
8933+
}
8934+
case MONO_PATCH_INFO_GSHARED_METHOD_INFO: {
8935+
MonoGSharedMethodInfo *info = (MonoGSharedMethodInfo*)patch_info->data.target;
8936+
8937+
for (int i = 0; i < info->num_entries; ++i) {
8938+
MonoRuntimeGenericContextInfoTemplate *entry = &info->entries [i];
8939+
MonoRgctxInfoType info_type = entry->info_type;
8940+
gpointer data = entry->data;
8941+
MonoJumpInfo tmp;
8942+
MonoJumpInfoType patch_type;
8943+
8944+
memset (&tmp, 0, sizeof (MonoJumpInfo));
8945+
8946+
patch_type = mini_rgctx_info_type_to_patch_info_type (info_type);
8947+
switch (patch_type) {
8948+
case MONO_PATCH_INFO_CLASS:
8949+
tmp.type = patch_type;
8950+
tmp.data.target = mono_class_from_mono_type_internal ((MonoType*)data);
8951+
break;
8952+
case MONO_PATCH_INFO_FIELD:
8953+
case MONO_PATCH_INFO_METHOD:
8954+
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
8955+
case MONO_PATCH_INFO_VIRT_METHOD:
8956+
case MONO_PATCH_INFO_GSHAREDVT_METHOD:
8957+
case MONO_PATCH_INFO_GSHAREDVT_CALL:
8958+
tmp.type = patch_type;
8959+
tmp.data.target = data;
8960+
break;
8961+
default:
8962+
break;
8963+
}
8964+
add_referenced_patch (acfg, &tmp, depth);
8965+
}
8966+
break;
8967+
}
8968+
default:
8969+
break;
8970+
}
8971+
}
8972+
88748973
/*
88758974
* compile_method:
88768975
*
@@ -9089,67 +9188,8 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
90899188
*/
90909189
depth = GPOINTER_TO_UINT (g_hash_table_lookup (acfg->method_depth, method));
90919190
if (!acfg->aot_opts.no_instances && depth < 32 && (mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts))) {
9092-
for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next) {
9093-
switch (patch_info->type) {
9094-
case MONO_PATCH_INFO_RGCTX_FETCH:
9095-
case MONO_PATCH_INFO_RGCTX_SLOT_INDEX:
9096-
case MONO_PATCH_INFO_METHOD:
9097-
case MONO_PATCH_INFO_METHOD_FTNDESC:
9098-
case MONO_PATCH_INFO_METHOD_RGCTX: {
9099-
MonoMethod *m = NULL;
9100-
9101-
if (patch_info->type == MONO_PATCH_INFO_RGCTX_FETCH || patch_info->type == MONO_PATCH_INFO_RGCTX_SLOT_INDEX) {
9102-
MonoJumpInfoRgctxEntry *e = patch_info->data.rgctx_entry;
9103-
9104-
if (e->info_type == MONO_RGCTX_INFO_GENERIC_METHOD_CODE || e->info_type == MONO_RGCTX_INFO_METHOD_FTNDESC)
9105-
m = e->data->data.method;
9106-
} else {
9107-
m = patch_info->data.method;
9108-
}
9109-
9110-
if (!m)
9111-
break;
9112-
if (m->is_inflated && (mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts))) {
9113-
if (!(mono_class_generic_sharing_enabled (m->klass) &&
9114-
mono_method_is_generic_sharable_full (m, FALSE, FALSE, FALSE)) &&
9115-
(!method_has_type_vars (m) || mono_method_is_generic_sharable_full (m, TRUE, TRUE, FALSE))) {
9116-
if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
9117-
if (mono_aot_mode_is_full (&acfg->aot_opts) && !method_has_type_vars (m))
9118-
add_extra_method_with_depth (acfg, mono_marshal_get_native_wrapper (m, TRUE, TRUE), depth + 1);
9119-
} else {
9120-
add_extra_method_with_depth (acfg, m, depth + 1);
9121-
add_types_from_method_header (acfg, m);
9122-
}
9123-
}
9124-
add_generic_class_with_depth (acfg, m->klass, depth + 5, "method");
9125-
}
9126-
if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) {
9127-
WrapperInfo *info = mono_marshal_get_wrapper_info (m);
9128-
9129-
if (info && info->subtype == WRAPPER_SUBTYPE_ELEMENT_ADDR)
9130-
add_extra_method_with_depth (acfg, m, depth + 1);
9131-
}
9132-
break;
9133-
}
9134-
case MONO_PATCH_INFO_VTABLE: {
9135-
MonoClass *klass = patch_info->data.klass;
9136-
9137-
if (mono_class_is_ginst (klass) && !mini_class_is_generic_sharable (klass))
9138-
add_generic_class_with_depth (acfg, klass, depth + 5, "vtable");
9139-
break;
9140-
}
9141-
case MONO_PATCH_INFO_SFLDA: {
9142-
MonoClass *klass = m_field_get_parent (patch_info->data.field);
9143-
9144-
/* The .cctor needs to run at runtime. */
9145-
if (mono_class_is_ginst (klass) && !mono_generic_context_is_sharable_full (&mono_class_get_generic_class (klass)->context, FALSE, FALSE) && mono_class_get_cctor (klass))
9146-
add_extra_method_with_depth (acfg, mono_class_get_cctor (klass), depth + 1);
9147-
break;
9148-
}
9149-
default:
9150-
break;
9151-
}
9152-
}
9191+
for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next)
9192+
add_referenced_patch (acfg, patch_info, depth);
91539193
}
91549194

91559195
/* Determine whenever the method has GOT slots */

0 commit comments

Comments
 (0)