+2010-03-06 Zoltan Varga <vargaz@gmail.com>
+
+ * tramp-amd64.c (mono_arch_create_monitor_exit_trampoline_full): Delegate
+ the handling of obj->synchronization == null and owner != current thread to
+ mono_monitor_exit ().
+
+ * tramp-x86.c (mono_arch_create_monitor_exit_trampoline_full): Ditto.
+
Sat Mar 6 18:14:15 CET 2010 Paolo Molaro <lupus@ximian.com>
{
guint8 *tramp;
guint8 *code, *buf;
- guint8 *jump_obj_null, *jump_have_waiters;
+ guint8 *jump_obj_null, *jump_have_waiters, *jump_sync_null, *jump_not_owned;
guint8 *jump_next;
int tramp_size;
int owner_offset, nest_offset, entry_count_offset;
amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, G_STRUCT_OFFSET (MonoObject, synchronisation), 8);
/* is synchronization null? */
amd64_test_reg_reg (code, AMD64_RCX, AMD64_RCX);
- /* if not, jump to next case */
- jump_next = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
- /* if yes, just return */
- amd64_ret (code);
+ /* if yes, jump to actual trampoline */
+ jump_sync_null = code;
+ amd64_branch8 (code, X86_CC_Z, -1, 1);
/* next case: synchronization is not null */
- x86_patch (jump_next, code);
/* load MonoInternalThread* into RDX */
code = mono_amd64_emit_tls_get (code, AMD64_RDX, mono_thread_get_tls_offset ());
/* load TID into RDX */
amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 8);
/* is synchronization->owner == TID */
amd64_alu_membase_reg_size (code, X86_CMP, AMD64_RCX, owner_offset, AMD64_RDX, 8);
- /* if yes, jump to next case */
- jump_next = code;
- amd64_branch8 (code, X86_CC_Z, -1, 1);
- /* if not, just return */
- amd64_ret (code);
+ /* if no, jump to actual trampoline */
+ jump_not_owned = code;
+ amd64_branch8 (code, X86_CC_NZ, -1, 1);
/* next case: synchronization->owner == TID */
- x86_patch (jump_next, code);
/* is synchronization->nest == 1 */
amd64_alu_membase_imm_size (code, X86_CMP, AMD64_RCX, nest_offset, 1, 4);
/* if not, jump to next case */
x86_patch (jump_obj_null, code);
x86_patch (jump_have_waiters, code);
+ x86_patch (jump_not_owned, code);
+ x86_patch (jump_sync_null, code);
}
/* jump to the actual trampoline */
{
guint8 *tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
guint8 *code, *buf;
- guint8 *jump_obj_null, *jump_have_waiters;
+ guint8 *jump_obj_null, *jump_have_waiters, *jump_sync_null, *jump_not_owned;
guint8 *jump_next;
int tramp_size;
int owner_offset, nest_offset, entry_count_offset;
x86_mov_reg_membase (buf, X86_ECX, X86_EAX, G_STRUCT_OFFSET (MonoObject, synchronisation), 4);
/* is synchronization null? */
x86_test_reg_reg (buf, X86_ECX, X86_ECX);
- /* if not, jump to next case */
- jump_next = buf;
- x86_branch8 (buf, X86_CC_NZ, -1, 1);
- /* if yes, just return */
- x86_ret (buf);
+ /* if yes, jump to actual trampoline */
+ jump_sync_null = buf;
+ x86_branch8 (buf, X86_CC_Z, -1, 1);
/* next case: synchronization is not null */
- x86_patch (jump_next, buf);
/* 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 (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 */
- jump_next = buf;
- x86_branch8 (buf, X86_CC_Z, -1, 1);
- /* if not, just return */
- x86_ret (buf);
+ /* if no, jump to actual trampoline */
+ jump_not_owned = buf;
+ x86_branch8 (buf, X86_CC_NZ, -1, 1);
/* next case: synchronization->owner == TID */
- x86_patch (jump_next, buf);
/* is synchronization->nest == 1 */
x86_alu_membase_imm (buf, X86_CMP, X86_ECX, nest_offset, 1);
/* if not, jump to next case */
/* push obj and jump to the actual trampoline */
x86_patch (jump_obj_null, buf);
x86_patch (jump_have_waiters, buf);
+ x86_patch (jump_not_owned, buf);
+ x86_patch (jump_sync_null, buf);
+
x86_push_reg (buf, X86_EAX);
x86_jump_code (buf, tramp);
} else {