#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"
mono_aot_register_jit_icall ("mono_amd64_throw_corlib_exception", mono_amd64_throw_corlib_exception);
mono_aot_register_jit_icall ("mono_amd64_resume_unwind", mono_amd64_resume_unwind);
mono_aot_register_jit_icall ("mono_amd64_get_original_ip", mono_amd64_get_original_ip);
- mono_aot_register_jit_icall ("mono_amd64_handler_block_trampoline_helper", mono_amd64_handler_block_trampoline_helper);
#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
mono_aot_register_jit_icall ("mono_amd64_start_gsharedvt_call", mono_amd64_start_gsharedvt_call);
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);
#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;
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)
#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);
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 ();
}
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)));
}
#endif
-gboolean
-mono_arch_print_tree (MonoInst *tree, int arity)
-{
- return 0;
-}
-
mgreg_t
mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
{
ctx->gregs [reg] = val;
}
-gpointer
-mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value)
-{
- gpointer *sp, old_value;
- char *bp;
-
- /*Load the spvar*/
- bp = (char *)MONO_CONTEXT_GET_BP (ctx);
- sp = (gpointer *)*(gpointer*)(bp + clause->exvar_offset);
-
- old_value = *sp;
- if (old_value < ji->code_start || (char*)old_value > ((char*)ji->code_start + ji->code_size))
- return old_value;
-
- *sp = new_value;
-
- return old_value;
-}
-
/*
* mono_arch_emit_load_aotconst:
*