Browse Source

[mixed] Add interp entry wrappers for devirtualized calls as well. (#17159)

* [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.
Zoltan Varga 6 years ago
parent
commit
d2f543b4b1
3 changed files with 36 additions and 11 deletions
  1. 32 10
      mono/mini/aot-compiler.c
  2. 3 0
      mono/mini/calls.c
  3. 1 1
      sdks/wasm/print-table.py

+ 32 - 10
mono/mini/aot-compiler.c

@@ -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;

+ 3 - 0
mono/mini/calls.c

@@ -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_) {

+ 1 - 1
sdks/wasm/print-table.py

@@ -6,7 +6,7 @@
 
 import sys
 
-prefix=" (elem (get_global $tableBase) "
+prefix=" (elem (i32.const 1) "
 
 if len(sys.argv) < 2:
     print "Usage: python print-table.py <path to mono.wast>"