From 1527834aeac4e2a0fe442a4342569234862788de Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 17 Aug 2020 17:15:40 -0400 Subject: [PATCH] [aot] Avoid emitting generic instances with vtype arguments on wasm to save space. (#40854) Co-authored-by: vargaz --- src/mono/mono/mini/aot-compiler.c | 28 ++++++++++++++++++++++++++-- src/mono/mono/mini/aot-runtime.c | 4 +++- src/mono/mono/mini/mini-generic-sharing.c | 15 +++++++++++++++ src/mono/mono/mini/mini.h | 3 +++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 4cb352e..5ca434f 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -5193,6 +5193,17 @@ check_type_depth (MonoType *t, int depth) static void add_types_from_method_header (MonoAotCompile *acfg, MonoMethod *method); +static gboolean +inst_has_vtypes (MonoGenericInst *inst) +{ + for (int i = 0; i < inst->type_argc; ++i) { + MonoType *t = inst->type_argv [i]; + if (MONO_TYPE_ISSTRUCT (t)) + return TRUE; + } + return FALSE; +} + /* * add_generic_class: * @@ -5205,6 +5216,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth, MonoClassField *field; gpointer iter; gboolean use_gsharedvt = FALSE; + gboolean use_gsharedvt_for_array = FALSE; if (!acfg->ginst_hash) acfg->ginst_hash = g_hash_table_new (NULL, NULL); @@ -5248,6 +5260,18 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth, (!strcmp (m_class_get_name (klass), "Dictionary`2") || !strcmp (m_class_get_name (klass), "List`1") || !strcmp (m_class_get_name (klass), "ReadOnlyCollection`1"))) use_gsharedvt = TRUE; +#ifdef TARGET_WASM + /* + * Use gsharedvt for instances with vtype arguments. + * 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)) { + use_gsharedvt = TRUE; + use_gsharedvt_for_array = TRUE; + } +#endif + iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if ((acfg->jit_opts & MONO_OPT_GSHAREDVT) && method->is_inflated && mono_method_get_context (method)->method_inst) { @@ -5256,7 +5280,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth, */ continue; } - + if (mono_method_is_generic_sharable_full (method, FALSE, FALSE, use_gsharedvt)) { /* Already added */ add_types_from_method_header (acfg, method); @@ -5337,7 +5361,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth, if (!strncmp (method->name, name_prefix, strlen (name_prefix))) { MonoMethod *m = mono_aot_get_array_helper_from_wrapper (method); - if (m->is_inflated && !mono_method_is_generic_sharable_full (m, FALSE, FALSE, FALSE)) + if (m->is_inflated && !mono_method_is_generic_sharable_full (m, FALSE, FALSE, use_gsharedvt_for_array)) add_extra_method_with_depth (acfg, m, depth); } } diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index b37c1dd..371cbe7 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4559,8 +4559,10 @@ mono_aot_can_dedup (MonoMethod *method) if (method->is_inflated && !mono_method_is_generic_sharable_full (method, TRUE, FALSE, FALSE) && !mini_is_gsharedvt_signature (mono_method_signature_internal (method)) && !mini_is_gsharedvt_klass (method->klass)) { - /* No point in dedup-ing private instances */ MonoGenericContext *context = mono_method_get_context (method); + if (context->method_inst && mini_is_gsharedvt_inst (context->method_inst)) + return FALSE; + /* No point in dedup-ing private instances */ if ((context->class_inst && inst_is_private (context->class_inst)) || (context->method_inst && inst_is_private (context->method_inst))) return FALSE; diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 86f7066..2ad21ec 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -4469,6 +4469,21 @@ mini_is_gsharedvt_sharable_inst (MonoGenericInst *inst) } gboolean +mini_is_gsharedvt_inst (MonoGenericInst *inst) +{ + int i; + + for (i = 0; i < inst->type_argc; ++i) { + MonoType *type = inst->type_argv [i]; + + if (mini_is_gsharedvt_type (type)) + return TRUE; + } + + return FALSE; +} + +gboolean mini_is_gsharedvt_sharable_method (MonoMethod *method) { MonoMethodSignature *sig; diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 58eb136..27e8313 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -2719,6 +2719,9 @@ mono_is_partially_sharable_inst (MonoGenericInst *inst); gboolean mini_is_gsharedvt_gparam (MonoType *t); +gboolean +mini_is_gsharedvt_inst (MonoGenericInst *inst); + MonoGenericContext* mini_method_get_context (MonoMethod *method); int mono_method_check_context_used (MonoMethod *method); -- 2.7.4