[mixed] Add interp entry wrappers for devirtualized calls as well. (mono/mono#17159)
authorZoltan Varga <vargaz@gmail.com>
Sun, 6 Oct 2019 00:51:52 +0000 (20:51 -0400)
committerGitHub <noreply@github.com>
Sun, 6 Oct 2019 00:51:52 +0000 (20:51 -0400)
* [mixed] Add interp entry wrappers for devirtualized calls as well.

* [aot] Generate code for string:memcpy/memset/bzero even in profile mode, they are called by the generated code.

* [aot] Treat string:memcpy as always AOTed in mono_aot_can_enter_interp () as well.

* [aot] Always aot string ctors as well, the JIT doesn't generate interp entry code for them.

* [wasm] Update print-table.py.

Commit migrated from https://github.com/mono/mono/commit/d2f543b4b1f10bb43a78da807888c3af01cfca25

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

index 012a0cd..d38f16b 100644 (file)
@@ -4445,12 +4445,28 @@ cleanup_true:
        return TRUE;
 }
 
+static gboolean
+always_aot (MonoMethod *method)
+{
+       /*
+        * Calls to these methods do not go through the normal call processing code so
+        * calling code cannot enter the interpreter. So always aot them even in profile guided aot mode.
+        */
+       if (method->klass == mono_get_string_class () && (strstr (method->name, "memcpy") || strstr (method->name, "bzero")))
+               return TRUE;
+       if (method->string_ctor)
+               return TRUE;
+       return FALSE;
+}
+
 gboolean
 mono_aot_can_enter_interp (MonoMethod *method)
 {
        MonoAotCompile *acfg = current_acfg;
 
        g_assert (acfg);
+       if (always_aot (method))
+               return FALSE;
        if (acfg->aot_opts.profile_only && !g_hash_table_lookup (acfg->profile_methods, method))
                return TRUE;
        return FALSE;
@@ -8557,17 +8573,23 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
 
        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;
+                       gboolean keep = FALSE;
+                       if (method->wrapper_type) {
+                               /* Keep most wrappers */
+                               WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+                               switch (info->subtype) {
+                               case WRAPPER_SUBTYPE_PTR_TO_STRUCTURE:
+                               case WRAPPER_SUBTYPE_STRUCTURE_TO_PTR:
+                                       break;
+                               default:
+                                       keep = TRUE;
+                                       break;
+                               }
                        }
+                       if (always_aot (method))
+                               keep = TRUE;
+                       if (!keep)
+                               return;
                } else {
                        if (!method->is_inflated)
                                return;
index b3f6eb8..9d8c522 100644 (file)
@@ -597,6 +597,9 @@ mini_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
                if (!virtual_ && cfg->llvm_only && cfg->interp && !tailcall && can_enter_interp (cfg, method, FALSE)) {
                        MonoInst *ftndesc = mini_emit_get_rgctx_method (cfg, -1, method, MONO_RGCTX_INFO_METHOD_FTNDESC);
 
+                       /* Need wrappers for this signature to be able to enter interpreter */
+                       cfg->interp_in_signatures = g_slist_prepend_mempool (cfg->mempool, cfg->interp_in_signatures, sig);
+
                        /* This call might need to enter the interpreter so make it indirect */
                        return mini_emit_llvmonly_calli (cfg, sig, args, ftndesc);
                } else if (!virtual_) {