#include <mono/metadata/monitor.h>
#include <mono/arch/x86/x86-codegen.h>
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-#include <valgrind/memcheck.h>
-#endif
+#include <mono/utils/memcheck.h>
#include "mini.h"
#include "mini-x86.h"
return start;
}
+gpointer
+mono_arch_get_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *m, int vt_offset)
+{
+ guint8 *code, *start;
+ int buf_len;
+ int this_offset;
+
+ buf_len = 32;
+
+ start = code = mono_domain_code_reserve (domain, buf_len);
+
+ this_offset = mono_x86_get_this_arg_offset (NULL, mono_method_signature (m));
+
+ /* Set imt arg */
+ x86_mov_reg_imm (code, MONO_ARCH_IMT_REG, m);
+ /* Load this */
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, this_offset + 4, 4);
+ /* Load vtable address */
+ x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0, 4);
+ x86_jump_membase (code, X86_EAX, vt_offset);
+
+ g_assert ((code - start) < buf_len);
+
+ mono_arch_flush_icache (start, code - start);
+
+ return start;
+}
+
void
mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
{
gboolean can_write = mono_breakpoint_clean_code (method_start, orig_code, 8, buf, sizeof (buf));
code = buf + 8;
- if (mono_running_on_valgrind ())
- can_write = FALSE;
/* go to the start of the call instruction
*
if (can_write) {
InterlockedExchange ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5);
-#ifdef HAVE_VALGRIND_MEMCHECK_H
- /* Tell valgrind to recompile the patched code */
- //VALGRIND_DISCARD_TRANSLATIONS (code + 2, code + 6);
-#endif
+ /* Tell valgrind to recompile the patched code */
+ VALGRIND_DISCARD_TRANSLATIONS (orig_code + 2, 4);
}
} else if (code [1] == 0xe9) {
/* A PLT entry: jmp <DISP> */
/* Then atomically change the first 4 bytes to a nop as well */
ops = 0x90909090;
InterlockedExchange ((gint32*)code, ops);
-#ifdef HAVE_VALGRIND_MEMCHECK_H
/* FIXME: the calltree skin trips on the self modifying code above */
/* Tell valgrind to recompile the patched code */
- //VALGRIND_DISCARD_TRANSLATIONS (code, code + 8);
-#endif
+ //VALGRIND_DISCARD_TRANSLATIONS (code, 8);
}
} else if (code [0] == 0x90 || code [0] == 0xeb) {
/* Already changed by another thread */
/* Put all registers into an array on the stack
* If this code is changed, make sure to update the offset value in
- * mono_arch_find_this_argument () in mini-x86.c.
+ * mono_arch_get_this_arg_from_call () in mini-x86.c.
*/
x86_push_reg (buf, X86_EDI);
x86_push_reg (buf, X86_ESI);
/* Check for thread interruption */
/* This is not perf critical code so no need to check the interrupt flag */
+ /* Align the stack on osx */
+ x86_alu_reg_imm (buf, X86_SUB, X86_ESP, 3 * 4);
x86_push_reg (buf, X86_EAX);
x86_call_code (buf, (guint8*)mono_thread_force_interruption_checkpoint);
x86_pop_reg (buf, X86_EAX);
+ x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 3 * 4);
/* Restore LMF */
jump_sync_null = buf;
x86_branch8 (buf, X86_CC_Z, -1, 1);
- /* load MonoThread* into EDX */
+ /* load MonoInternalThread* into EDX */
buf = mono_x86_emit_tls_get (buf, X86_EDX, mono_thread_get_tls_offset ());
/* load TID into EDX */
- x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
+ x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 4);
/* is synchronization->owner null? */
x86_alu_membase_imm (buf, X86_CMP, X86_ECX, owner_offset, 0);
/* next case: synchronization is not null */
x86_patch (jump_next, buf);
- /* load MonoThread* into EDX */
+ /* load MonoInternalThread* into EDX */
buf = mono_x86_emit_tls_get (buf, X86_EDX, mono_thread_get_tls_offset ());
/* load TID into EDX */
- x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
+ x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 4);
/* is synchronization->owner == TID */
x86_alu_membase_reg (buf, X86_CMP, X86_ECX, owner_offset, X86_EDX);
/* if yes, jump to next case */