2009-12-13 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sun, 13 Dec 2009 16:03:52 +0000 (16:03 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 13 Dec 2009 16:03:52 +0000 (16:03 -0000)
* method-to-ir.c mini-llvm.c: Fix support for monitor enter/exit trampolines
in the LLVM backend on AMD64.

svn path=/trunk/mono/; revision=148348

mono/mini/ChangeLog
mono/mini/method-to-ir.c
mono/mini/mini-llvm.c
mono/mini/mini.c

index 389fca577875fa7279c1122d7dd62849fe0273b2..4bb4dfcf88b4cdca7310121da56186a9555e592f 100644 (file)
@@ -1,5 +1,8 @@
 2009-12-13  Zoltan Varga  <vargaz@gmail.com>
 
+       * method-to-ir.c mini-llvm.c: Fix support for monitor enter/exit trampolines
+       in the LLVM backend on AMD64.
+
        * aot-runtime.c (decode_eh_frame): Initialize the clauses from the info in the
        FDE.
 
index 2b31195117ade2001f43f1bd7056546c0217acbe..89e9526772121b7377d62e70b2cb5409ec81ed20 100644 (file)
@@ -117,6 +117,7 @@ extern MonoMethodSignature *helper_sig_domain_get;
 extern MonoMethodSignature *helper_sig_generic_class_init_trampoline;
 extern MonoMethodSignature *helper_sig_rgctx_lazy_fetch_trampoline;
 extern MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline;
+extern MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline_llvm;
 
 /*
  * Instruction metadata
@@ -3923,19 +3924,31 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                if (strcmp (cmethod->name, "Enter") == 0) {
                        MonoCallInst *call;
 
-                       call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER,
-                                       NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
-                       mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
-                                       MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
+                       if (COMPILE_LLVM (cfg)) {
+                               /* 
+                                * Pass the argument normally, the LLVM backend will handle the
+                                * calling convention problems.
+                                */
+                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER, NULL, helper_sig_monitor_enter_exit_trampoline_llvm, args);
+                       } else {
+                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER,
+                                           NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
+                               mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
+                                                                                          MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
+                       }
 
                        return (MonoInst*)call;
                } else if (strcmp (cmethod->name, "Exit") == 0) {
                        MonoCallInst *call;
 
-                       call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT,
-                                       NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
-                       mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
-                                       MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
+                       if (COMPILE_LLVM (cfg)) {
+                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT, NULL, helper_sig_monitor_enter_exit_trampoline_llvm, args);
+                       } else {
+                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT,
+                                           NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
+                               mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
+                                                                                          MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
+                       }
 
                        return (MonoInst*)call;
                }
index 0074d00f52f305c3a20bae81eb3946ed4fb65197..8d2b485f53e1001cc88e227658f15d681280b48b 100644 (file)
@@ -2530,12 +2530,13 @@ mono_llvm_emit_method (MonoCompile *cfg)
                                                                MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
                                                                if (abs_ji) {
                                                                        /*
-                                                                        * The monitor entry/exit trampolines have their
-                                                                        * own calling convention, and call->signature
-                                                                        * doesn't include the argument.
+                                                                        * The monitor entry/exit trampolines might have
+                                                                        * their own calling convention on some platforms.
                                                                         */
+#ifndef TARGET_AMD64
                                                                        if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
                                                                                LLVM_FAILURE (ctx, "monitor enter/exit");
+#endif
                                                                        target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
                                                                        LLVMAddGlobalMapping (ee, callee, target);
                                                                }
index 1fe9e66641c9fdc06dc238d06e969f6a4fc3e668..9aaab81e24fa202a2773a588ac6440f9b6602163 100644 (file)
@@ -76,6 +76,7 @@ MonoMethodSignature *helper_sig_domain_get = NULL;
 MonoMethodSignature *helper_sig_generic_class_init_trampoline = NULL;
 MonoMethodSignature *helper_sig_rgctx_lazy_fetch_trampoline = NULL;
 MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline = NULL;
+MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline_llvm = NULL;
 
 static guint32 default_opt = 0;
 static gboolean default_opt_set = FALSE;
@@ -1308,6 +1309,7 @@ create_helper_signature (void)
        helper_sig_generic_class_init_trampoline = mono_create_icall_signature ("void");
        helper_sig_rgctx_lazy_fetch_trampoline = mono_create_icall_signature ("ptr ptr");
        helper_sig_monitor_enter_exit_trampoline = mono_create_icall_signature ("void");
+       helper_sig_monitor_enter_exit_trampoline_llvm = mono_create_icall_signature ("void object");
 }
 
 static gconstpointer