From 9c91a8ec2d88edd23ab66f8808107691a6f39ff1 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Mon, 27 Feb 2023 16:16:27 +0100 Subject: [PATCH 1/5] Enable direct call transformation where caller requires no initialization --- src/mono/mono/mini/aot-compiler.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 4481c694d36c8..7156d7de944ba 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6588,12 +6588,10 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui direct_call_target = symbol; patch_info->type = MONO_PATCH_INFO_NONE; } else if ((m_class_get_image (patch_info->data.method->klass) == acfg->image) && !got_only && is_direct_callable (acfg, method, patch_info)) { -#if 0 - // FIXME: Currently not used. It fails as some callees require initialization. MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod); - // Don't compile inflated methods if we're doing dedup - if (acfg->aot_opts.dedup && !mono_aot_can_dedup (cmethod)) { + // Enable direct call transformation where caller's class requires no initialization + if (!m_class_has_static_refs (method->klass)) { char *name = mono_aot_get_mangled_method_name (cmethod); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); g_free (name); @@ -6603,7 +6601,6 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui patch_info->type = MONO_PATCH_INFO_NONE; acfg->stats.direct_calls ++; } -#endif } acfg->stats.all_calls ++; From 8f995a13f3f5f574c64c077b45d0a5f3a49ac868 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Mon, 27 Feb 2023 18:16:59 +0100 Subject: [PATCH 2/5] Callee can specialize --- src/mono/mono/mini/aot-compiler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 7156d7de944ba..8fa2f25c8315a 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6590,8 +6590,8 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui } else if ((m_class_get_image (patch_info->data.method->klass) == acfg->image) && !got_only && is_direct_callable (acfg, method, patch_info)) { MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod); - // Enable direct call transformation where caller's class requires no initialization - if (!m_class_has_static_refs (method->klass)) { + // Enable direct call transformation where caller's class requires no initialization and callee can specialize + if (!m_class_has_static_refs (method->klass) && mono_aot_can_specialize (cmethod)) { char *name = mono_aot_get_mangled_method_name (cmethod); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); g_free (name); From 882353ea456b8dcbb738dce9cfa16afc1600526c Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Tue, 28 Feb 2023 13:38:04 +0100 Subject: [PATCH 3/5] Use m_class_has_cctor method to check if class requires no initialization --- src/mono/mono/mini/aot-compiler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 8fa2f25c8315a..7c0c46271a9ff 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6591,7 +6591,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod); // Enable direct call transformation where caller's class requires no initialization and callee can specialize - if (!m_class_has_static_refs (method->klass) && mono_aot_can_specialize (cmethod)) { + if (!m_class_has_cctor (method->klass) && mono_aot_can_specialize (cmethod)) { char *name = mono_aot_get_mangled_method_name (cmethod); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); g_free (name); From 1a182a12095479f77bed47557d8febabdc5779ce Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Wed, 1 Mar 2023 17:02:47 +0100 Subject: [PATCH 4/5] Move the condition into is_direct_callable --- src/mono/mono/mini/aot-compiler.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 7c0c46271a9ff..a130c2479dc32 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6287,6 +6287,8 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc if (direct_callable && !strcmp (callee_cfg->method->name, ".cctor")) direct_callable = FALSE; + if (direct_callable && (m_class_has_cctor (method->klass) || !mono_aot_can_specialize (callee_cfg->method))) + direct_callable = FALSE; // // FIXME: Support inflated methods, it asserts in mini_llvm_init_gshared_method_this () because the method is not in // amodule->extra_methods. @@ -6589,18 +6591,14 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui patch_info->type = MONO_PATCH_INFO_NONE; } else if ((m_class_get_image (patch_info->data.method->klass) == acfg->image) && !got_only && is_direct_callable (acfg, method, patch_info)) { MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod); + char *name = mono_aot_get_mangled_method_name (cmethod); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); + g_free (name); - // Enable direct call transformation where caller's class requires no initialization and callee can specialize - if (!m_class_has_cctor (method->klass) && mono_aot_can_specialize (cmethod)) { - char *name = mono_aot_get_mangled_method_name (cmethod); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); - g_free (name); - - direct_call = TRUE; - direct_call_target = callee_cfg->asm_symbol; - patch_info->type = MONO_PATCH_INFO_NONE; - acfg->stats.direct_calls ++; - } + direct_call = TRUE; + direct_call_target = callee_cfg->asm_symbol; + patch_info->type = MONO_PATCH_INFO_NONE; + acfg->stats.direct_calls ++; } acfg->stats.all_calls ++; From 282fb7efa620f1f114400b90b31be6ddc9a47386 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Thu, 2 Mar 2023 10:09:03 +0100 Subject: [PATCH 5/5] Revert last commit --- src/mono/mono/mini/aot-compiler.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index a130c2479dc32..6c264ff25b1af 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6287,8 +6287,6 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc if (direct_callable && !strcmp (callee_cfg->method->name, ".cctor")) direct_callable = FALSE; - if (direct_callable && (m_class_has_cctor (method->klass) || !mono_aot_can_specialize (callee_cfg->method))) - direct_callable = FALSE; // // FIXME: Support inflated methods, it asserts in mini_llvm_init_gshared_method_this () because the method is not in // amodule->extra_methods. @@ -6591,14 +6589,17 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui patch_info->type = MONO_PATCH_INFO_NONE; } else if ((m_class_get_image (patch_info->data.method->klass) == acfg->image) && !got_only && is_direct_callable (acfg, method, patch_info)) { MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod); - char *name = mono_aot_get_mangled_method_name (cmethod); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); - g_free (name); - direct_call = TRUE; - direct_call_target = callee_cfg->asm_symbol; - patch_info->type = MONO_PATCH_INFO_NONE; - acfg->stats.direct_calls ++; + if (!m_class_has_cctor (method->klass) && mono_aot_can_specialize (callee_cfg->method)) { + char *name = mono_aot_get_mangled_method_name (cmethod); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_name (method, TRUE) : ""); + g_free (name); + + direct_call = TRUE; + direct_call_target = callee_cfg->asm_symbol; + patch_info->type = MONO_PATCH_INFO_NONE; + acfg->stats.direct_calls ++; + } } acfg->stats.all_calls ++;