this_reg = mono_arch_get_this_arg_reg (mono_method_signature (m), gsctx, NULL);
- mono_domain_lock (domain);
- start = code = mono_code_manager_reserve (domain->code_mp, 20);
- mono_domain_unlock (domain);
+ start = code = mono_domain_code_reserve (domain, 20);
amd64_alu_reg_imm (code, X86_ADD, this_reg, sizeof (MonoObject));
/* FIXME: Optimize this */
return start;
}
+/*
+ * mono_arch_get_static_rgctx_trampoline:
+ *
+ * Create a trampoline which sets RGCTX_REG to MRGCTX, then jumps to ADDR.
+ */
+gpointer
+mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
+{
+ guint8 *code, *start;
+ int buf_len;
+
+ MonoDomain *domain = mono_domain_get ();
+
+#ifdef MONO_ARCH_NOMAP32BIT
+ buf_len = 32;
+#else
+ /* AOTed code could still have a non-32 bit address */
+ if ((((guint64)addr) >> 32) == 0)
+ buf_len = 16;
+ else
+ buf_len = 30;
+#endif
+
+ start = code = mono_domain_code_reserve (domain, buf_len);
+
+ amd64_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, mrgctx);
+ amd64_jump_code (code, addr);
+ g_assert ((code - start) < buf_len);
+
+ mono_arch_flush_icache (start, code - start);
+
+ return start;
+}
+
/*
* mono_arch_patch_callsite:
*
gpointer *vtable_slot;
/* call *<OFFSET>(%rip) */
- vtable_slot = mono_arch_get_vcall_slot_addr (code + 3, (gpointer*)regs);
+ vtable_slot = mono_get_vcall_slot_addr (code + 3, (gpointer*)regs);
g_assert (vtable_slot);
*vtable_slot = nullified_class_init_trampoline;
} else if (code [-2] == 0xe8) {
/* call <TARGET> */
- guint8 *buf = code - 2;
-
+ //guint8 *buf = code - 2;
+
+ /*
+ * It would be better to replace the call with nops, but that doesn't seem
+ * to work on SMP machines even when the whole call is inside a cache line.
+ * Patching the call address seems to work.
+ */
+ /*
buf [0] = 0x66;
buf [1] = 0x66;
buf [2] = 0x90;
buf [3] = 0x66;
buf [4] = 0x90;
+ */
+
+ mono_arch_patch_callsite (code - 2, code - 2 + 5, nullified_class_init_trampoline);
} else if ((code [0] == 0x41) && (code [1] == 0xff)) {
/* call <REG> */
/* happens on machines without MAP_32BIT like freebsd */
{
MonoJumpInfo *ji;
guint32 code_size;
+ guchar *code;
+ GSList *unwind_ops, *l;
+
+ code = mono_arch_create_trampoline_code_full (tramp_type, &code_size, &ji, &unwind_ops, FALSE);
+
+ mono_save_trampoline_xdebug_info ("<generic_trampoline>", code, code_size, unwind_ops);
+
+ for (l = unwind_ops; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (unwind_ops);
- return mono_arch_create_trampoline_code_full (tramp_type, &code_size, &ji, FALSE);
+ return code;
}
guchar*
-mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, GSList **out_unwind_ops, gboolean aot)
{
guint8 *buf, *code, *tramp, *br [2], *r11_save_code, *after_r11_save_code;
int i, lmf_offset, offset, res_offset, arg_offset, rax_offset, tramp_offset, saved_regs_offset;
int saved_fpregs_offset, rbp_offset, framesize, orig_rsp_to_rbp_offset, cfa_offset;
gboolean has_caller;
GSList *unwind_ops = NULL;
- GSList *l;
if (tramp_type == MONO_TRAMPOLINE_JUMP)
has_caller = FALSE;
nullified_class_init_trampoline = mono_arch_get_nullified_class_init_trampoline (&code_len);
}
- mono_save_trampoline_xdebug_info ("<generic_trampoline>", buf, *code_size, unwind_ops);
-
- for (l = unwind_ops; l; l = l->next)
- g_free (l->data);
- g_slist_free (unwind_ops);
+ *out_unwind_ops = unwind_ops;
return buf;
}
else
size = 5 + 1 + 8;
- mono_domain_lock (domain);
- code = buf = mono_code_manager_reserve_align (domain->code_mp, size, 1);
- mono_domain_unlock (domain);
+ code = buf = mono_domain_code_reserve_align (domain, size, 1);
amd64_call_code (code, tramp);
/* The trampoline code will obtain the argument from the instruction stream */
int tramp_size;
int owner_offset, nest_offset, dummy;
+ *ji = NULL;
+
g_assert (MONO_ARCH_MONITOR_OBJECT_REG == AMD64_RDI);
mono_monitor_threads_sync_members_offset (&owner_offset, &nest_offset, &dummy);
int tramp_size;
int owner_offset, nest_offset, entry_count_offset;
+ *ji = NULL;
+
g_assert (MONO_ARCH_MONITOR_OBJECT_REG == AMD64_RDI);
mono_monitor_threads_sync_members_offset (&owner_offset, &nest_offset, &entry_count_offset);