[interp] Don't inline empty calls that take vt arguments.
[mono.git] / mono / mini / mini-amd64.c
index 5a376b8945017f49fa82fb49d444b81c8b19cc0e..949f8946ddd1c73cf2a3d56a303448eff7115656 100644 (file)
@@ -37,6 +37,7 @@
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/unlocked.h>
 
 #include "trace.h"
 #include "ir-emit.h"
@@ -2869,6 +2870,11 @@ emit_call_body (MonoCompile *cfg, guint8 *code, MonoJumpInfoType patch_type, gco
                        amd64_call_code (code, 0);
                }
                else {
+                       if (!no_patch && ((guint32)(code + 2 - cfg->native_code) % 8) != 0) {
+                               guint32 pad_size = 8 - ((guint32)(code + 2 - cfg->native_code) % 8);
+                               amd64_padding (code, pad_size);
+                               g_assert ((guint64)(code + 2 - cfg->native_code) % 8 == 0);
+                       }
                        mono_add_patch_info (cfg, code - cfg->native_code, patch_type, data);
                        amd64_set_reg_template (code, GP_SCRATCH_REG);
                        amd64_call_reg (code, GP_SCRATCH_REG);
@@ -3644,7 +3650,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
 #define EXTRA_CODE_SPACE (16)
 
-               if (G_UNLIKELY (offset > (cfg->code_size - max_len - EXTRA_CODE_SPACE))) {
+               if (G_UNLIKELY ((offset + max_len + EXTRA_CODE_SPACE) > cfg->code_size)) {
                        cfg->code_size *= 2;
                        cfg->native_code = (unsigned char *)mono_realloc_native_code(cfg);
                        code = cfg->native_code + offset;
@@ -4481,6 +4487,17 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        g_assert (!cfg->method->save_lmf);
 
+                       /* the size of the tailcall op depends on signature, let's check for enough
+                        * space in the code buffer here again */
+                       max_len += AMD64_NREG * 4 + call->stack_usage * 15 + EXTRA_CODE_SPACE;
+
+                       if (G_UNLIKELY (offset + max_len > cfg->code_size)) {
+                               cfg->code_size *= 2;
+                               cfg->native_code = (unsigned char *) mono_realloc_native_code(cfg);
+                               code = cfg->native_code + offset;
+                               cfg->stat_code_reallocs++;
+                       }
+
                        /* Restore callee saved registers */
                        save_area_offset = cfg->arch.reg_save_area_offset;
                        for (i = 0; i < AMD64_NREG; ++i)
@@ -4511,7 +4528,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 #endif
                        }
 
-                       offset = code - cfg->native_code;
                        mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method);
                        if (cfg->compile_aot)
                                amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 0, 8);
@@ -6419,6 +6435,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_GET_LAST_ERROR:
                        emit_get_last_error(code, ins->dreg);
                        break;
+               case OP_FILL_PROF_CALL_CTX:
+                       for (int i = 0; i < AMD64_NREG; i++)
+                               if (AMD64_IS_CALLEE_SAVED_REG (i) || i == AMD64_RSP)
+                                       amd64_mov_membase_reg (code, ins->sreg1, MONO_STRUCT_OFFSET (MonoContext, gregs) + i * sizeof (mgreg_t), i, sizeof (mgreg_t));
+                       break;
                default:
                        g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
                        g_assert_not_reached ();
@@ -8006,7 +8027,7 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC
        }
 
        if (!fail_tramp)
-               mono_stats.imt_trampolines_size += code - start;
+               UnlockedAdd (&mono_stats.imt_trampolines_size, code - start);
        g_assert (code - start <= size);
        g_assert_checked (mono_arch_unwindinfo_validate_size (unwind_ops, MONO_TRAMPOLINE_UNWINDINFO_SIZE(0)));
 
@@ -8113,12 +8134,6 @@ mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMetho
 }
 #endif
 
-gboolean
-mono_arch_print_tree (MonoInst *tree, int arity)
-{
-       return 0;
-}
-
 mgreg_t
 mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
 {