[aot] Emit interp entry code for methods which are not AOTed when using AOT profiling...
authorZoltan Varga <vargaz@gmail.com>
Wed, 11 Sep 2019 04:11:51 +0000 (00:11 -0400)
committerLarry Ewing <lewing@microsoft.com>
Wed, 11 Sep 2019 12:44:34 +0000 (07:44 -0500)
Commit migrated from https://github.com/mono/mono/commit/52d24a57d266d52db53381962e11e5416d3ff1f2

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

index 4cf6c8c..0eed864 100644 (file)
@@ -409,6 +409,7 @@ typedef struct {
 
 /* This points to the current acfg in LLVM mode */
 static MonoAotCompile *llvm_acfg;
+static MonoAotCompile *current_acfg;
 
 /* Cache of decoded method external icall symbol names. */
 /* Owned by acfg, but kept in this static as well since it is */
@@ -4434,6 +4435,17 @@ cleanup_true:
        return TRUE;
 }
 
+gboolean
+mono_aot_can_enter_interp (MonoMethod *method)
+{
+       MonoAotCompile *acfg = current_acfg;
+
+       g_assert (acfg);
+       if (acfg->aot_opts.profile_only && !g_hash_table_lookup (acfg->profile_methods, method))
+               return TRUE;
+       return FALSE;
+}
+
 static void
 add_wrappers (MonoAotCompile *acfg)
 {
@@ -8444,8 +8456,24 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
        if (method->wrapper_type == MONO_WRAPPER_COMINTEROP)
                return;
 
-       if (acfg->aot_opts.profile_only && !method->is_inflated && !g_hash_table_lookup (acfg->profile_methods, method))
-               return;
+       if (acfg->aot_opts.profile_only && !g_hash_table_lookup (acfg->profile_methods, method)) {
+               if (acfg->aot_opts.llvm_only) {
+                       /* Keep wrappers */
+                       if (!method->wrapper_type)
+                               return;
+                       WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+                       switch (info->subtype) {
+                       case WRAPPER_SUBTYPE_PTR_TO_STRUCTURE:
+                       case WRAPPER_SUBTYPE_STRUCTURE_TO_PTR:
+                               return;
+                       default:
+                               break;
+                       }
+               } else {
+                       if (!method->is_inflated)
+                               return;
+               }
+       }
 
        mono_atomic_inc_i32 (&acfg->stats.mcount);
 
@@ -13555,6 +13583,8 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options,
        acfg->plt_offset = 1;
        add_preinit_got_slots (acfg);
 
+       current_acfg = acfg;
+
 #ifdef ENABLE_LLVM
        if (acfg->llvm) {
                llvm_acfg = acfg;
@@ -13616,6 +13646,8 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options,
                /* We only collected methods from this assembly */
                return 0;
 
+       current_acfg = NULL;
+
        return emit_aot_image (acfg);
 }
 
@@ -13985,4 +14017,10 @@ mono_aot_direct_icalls_enabled_for_method (MonoCompile *cfg, MonoMethod *method)
        return 0;
 }
 
+gboolean
+mono_aot_can_enter_interp (MonoMethod *method)
+{
+       return FALSE;
+}
+
 #endif
index 6b8803b..a379c01 100644 (file)
@@ -23,9 +23,6 @@ char*    mono_aot_get_direct_call_symbol    (MonoJumpInfoType type, gconstpointe
 int      mono_aot_get_method_index          (MonoMethod *method) MONO_LLVM_INTERNAL;
 MonoJumpInfo* mono_aot_patch_info_dup       (MonoJumpInfo* ji) MONO_LLVM_INTERNAL;
 gboolean mono_aot_can_specialize (MonoMethod *method) MONO_LLVM_INTERNAL;
+gboolean mono_aot_can_enter_interp (MonoMethod *method) MONO_LLVM_INTERNAL;
 
 #endif
-
-
-
-
index 08930f8..b3f6eb8 100644 (file)
@@ -13,6 +13,7 @@
 #include "llvmonly-runtime.h"
 #include "mini-llvm.h"
 #include "jit-icalls.h"
+#include "aot-compiler.h"
 #include <mono/metadata/abi-details.h>
 #include <mono/metadata/class-abi-details.h>
 #include <mono/utils/mono-utils-debug.h>
@@ -425,9 +426,15 @@ can_enter_interp (MonoCompile *cfg, MonoMethod *method, gboolean virtual_)
 {
        if (method->wrapper_type)
                return FALSE;
-       /* Virtual calls from corlib can go outside corlib */
-       if ((m_class_get_image (method->klass) == m_class_get_image (cfg->method->klass)) && !virtual_)
-               return FALSE;
+
+       if (m_class_get_image (method->klass) == m_class_get_image (cfg->method->klass)) {
+               /* When using AOT profiling, the method might not be AOTed */
+               if (cfg->compile_aot && mono_aot_can_enter_interp (method))
+                       return TRUE;
+               /* Virtual calls from corlib can go outside corlib */
+               if (!virtual_)
+                       return FALSE;
+       }
 
        /* See needs_extra_arg () in mini-llvm.c */
        if (method->string_ctor)