Merge pull request #2183 from joelmartinez/monodoc-ecmacref-fix
[mono.git] / mono / mini / mini-trampolines.c
index 9f7d946db4a7100fb99fcfc15202794c2f9f07c3..fb6d1f62e1dc12978dcfddeabc8e587e5ec142aa 100644 (file)
@@ -340,7 +340,7 @@ mini_add_method_trampoline (MonoMethod *m, gpointer compiled_method, gboolean ad
                }
        }
 
-       if (ji)
+       if (ji && !ji->is_trampoline)
                jmethod = jinfo_get_method (ji);
        if (callee_gsharedvt && mini_is_gsharedvt_variable_signature (mono_method_signature (jmethod))) {
                MonoMethodSignature *sig, *gsig;
@@ -361,11 +361,14 @@ mini_add_method_trampoline (MonoMethod *m, gpointer compiled_method, gboolean ad
                /* FIXME: ji->from_aot is not set for llvm methods */
                if (ji && (ji->from_aot || mono_aot_only)) {
                        /* In AOT mode, compiled_method points to one of the InternalArray methods in Array. */
-                       if (mono_method_needs_static_rgctx_invoke (jinfo_get_method (ji), TRUE))
+                       if (!mono_llvm_only && mono_method_needs_static_rgctx_invoke (jinfo_get_method (ji), TRUE))
                                add_static_rgctx_tramp = TRUE;
                }
        }
 
+       if (mono_llvm_only)
+               add_static_rgctx_tramp = FALSE;
+
        if (add_static_rgctx_tramp)
                addr = mono_create_static_rgctx_trampoline (m, addr);
 
@@ -703,7 +706,7 @@ mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
 static gpointer
 mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
 {
-       MonoObject *this;
+       MonoObject *this_arg;
        MonoVTable *vt;
        gpointer *vtable_slot;
        MonoMethod *m;
@@ -722,10 +725,10 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
        /*
         * Obtain the vtable from the 'this' arg.
         */
-       this = mono_arch_get_this_arg_from_call (regs, code);
-       g_assert (this);
+       this_arg = mono_arch_get_this_arg_from_call (regs, code);
+       g_assert (this_arg);
 
-       vt = this->vtable;
+       vt = this_arg->vtable;
 
        if (slot >= 0) {
                /* Normal virtual call */
@@ -896,29 +899,6 @@ mono_rgctx_lazy_fetch_trampoline (mgreg_t *regs, guint8 *code, gpointer data, gu
                return mono_class_fill_runtime_generic_context (arg, index);
 }
 
-void
-mono_monitor_enter_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-       mono_monitor_enter (obj);
-}
-
-void
-mono_monitor_enter_v4_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
-       char *lock_taken = (char*)regs [MONO_ARCH_MONITOR_LOCK_TAKEN_REG];
-       mono_monitor_enter_v4 (obj, lock_taken);
-#else
-       g_assert_not_reached ();
-#endif
-}
-
-void
-mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-       mono_monitor_exit (obj);
-}
-
 /*
  * Precompute data to speed up mono_delegate_trampoline ().
  * METHOD might be NULL.
@@ -1025,7 +1005,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
                                }
                        }
                }
-       } else {
+       // If "delegate->method_ptr" is null mono_get_addr_from_ftnptr will fail if
+       // ftnptrs are being used.  "method" would end up null on archtitectures without
+       // ftnptrs so we can just skip this.
+       } else if (delegate->method_ptr) {
                ji = mono_jit_info_table_find (domain, mono_get_addr_from_ftnptr (delegate->method_ptr));
                if (ji)
                        method = jinfo_get_method (ji);
@@ -1171,7 +1154,7 @@ mono_create_handler_block_trampoline (void)
                gpointer tmp;
 
                tmp = mono_arch_create_handler_block_trampoline (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                mono_memory_barrier ();
                code = tmp;
        }
@@ -1210,12 +1193,6 @@ mono_get_trampoline_func (MonoTrampolineType tramp_type)
        case MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING:
                return mono_generic_virtual_remoting_trampoline;
 #endif
-       case MONO_TRAMPOLINE_MONITOR_ENTER:
-               return mono_monitor_enter_trampoline;
-       case MONO_TRAMPOLINE_MONITOR_ENTER_V4:
-               return mono_monitor_enter_v4_trampoline;
-       case MONO_TRAMPOLINE_MONITOR_EXIT:
-               return mono_monitor_exit_trampoline;
        case MONO_TRAMPOLINE_VCALL:
                return mono_vcall_trampoline;
 #ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
@@ -1235,7 +1212,7 @@ create_trampoline_code (MonoTrampolineType tramp_type)
        guchar *code;
 
        code = mono_arch_create_generic_trampoline (tramp_type, &info, FALSE);
-       mono_tramp_info_register (info);
+       mono_tramp_info_register (info, NULL);
 
        return code;
 }
@@ -1260,9 +1237,6 @@ mono_trampolines_init (void)
 #ifndef DISABLE_REMOTING
        mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
 #endif
-       mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER);
-       mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER_V4] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER_V4);
-       mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_EXIT] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
        mono_trampoline_code [MONO_TRAMPOLINE_VCALL] = create_trampoline_code (MONO_TRAMPOLINE_VCALL);
 #ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
        mono_trampoline_code [MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD] = create_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
@@ -1320,6 +1294,9 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad
        if (code && !ji->has_generic_jit_info && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
                return code;
 
+       if (mono_llvm_only)
+               return mono_jit_compile_method (method);
+
        mono_domain_lock (domain);
        code = g_hash_table_lookup (domain_jit_info (domain)->jump_trampoline_hash, method);
        mono_domain_unlock (domain);
@@ -1348,6 +1325,12 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad
        return ji->code_start;
 }
 
+static void
+method_not_found (void)
+{
+       g_assert_not_reached ();
+}
+
 gpointer
 mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
 {
@@ -1359,6 +1342,14 @@ mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
                
                if (code)
                        return code;
+               if (mono_llvm_only) {
+                       if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST || method->wrapper_type == MONO_WRAPPER_LDFLD_REMOTE ||
+                               method->wrapper_type == MONO_WRAPPER_STFLD_REMOTE)
+                               /* These wrappers are not generated */
+                               return method_not_found;
+                       /* Methods are lazily initialized on first call, so this can't lead recursion */
+                       return mono_compile_method (method);
+               }
        }
 
        mono_domain_lock (domain);
@@ -1442,9 +1433,18 @@ mono_create_delegate_trampoline_info (MonoDomain *domain, MonoClass *klass, Mono
        return tramp_info;
 }
 
+static void
+no_delegate_trampoline (void)
+{
+       g_assert_not_reached ();
+}
+
 gpointer
 mono_create_delegate_trampoline (MonoDomain *domain, MonoClass *klass)
 {
+       if (mono_llvm_only)
+               return no_delegate_trampoline;
+
        return mono_create_delegate_trampoline_info (domain, klass, NULL)->invoke_impl;
 }
 
@@ -1479,7 +1479,7 @@ mono_create_rgctx_lazy_fetch_trampoline (guint32 offset)
                ptr = mono_aot_get_lazy_fetch_trampoline (offset);
        } else {
                tramp = mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                ptr = mono_create_ftnptr (mono_get_root_domain (), tramp);
        }
 
@@ -1502,95 +1502,6 @@ mono_create_rgctx_lazy_fetch_trampoline (guint32 offset)
 
        return ptr;
 }
-
-gpointer
-mono_create_monitor_enter_trampoline (void)
-{
-       static gpointer code;
-
-       if (mono_aot_only) {
-               if (!code)
-                       code = mono_aot_get_trampoline ("monitor_enter_trampoline");
-               return code;
-       }
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-       mono_trampolines_lock ();
-
-       if (!code) {
-               MonoTrampInfo *info;
-
-               code = mono_arch_create_monitor_enter_trampoline (&info, FALSE, FALSE);
-               mono_tramp_info_register (info);
-       }
-
-       mono_trampolines_unlock ();
-#else
-       code = NULL;
-       g_assert_not_reached ();
-#endif
-
-       return code;
-}
-
-gpointer
-mono_create_monitor_enter_v4_trampoline (void)
-{
-       static gpointer code;
-
-       if (mono_aot_only) {
-               if (!code)
-                       code = mono_aot_get_trampoline ("monitor_enter_v4_trampoline");
-               return code;
-       }
-
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG) && defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
-       mono_trampolines_lock ();
-
-       if (!code) {
-               MonoTrampInfo *info;
-
-               code = mono_arch_create_monitor_enter_trampoline (&info, TRUE, FALSE);
-               mono_tramp_info_register (info);
-       }
-
-       mono_trampolines_unlock ();
-#else
-       code = NULL;
-       g_assert_not_reached ();
-#endif
-
-       return code;
-}
-
-gpointer
-mono_create_monitor_exit_trampoline (void)
-{
-       static gpointer code;
-
-       if (mono_aot_only) {
-               if (!code)
-                       code = mono_aot_get_trampoline ("monitor_exit_trampoline");
-               return code;
-       }
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-       mono_trampolines_lock ();
-
-       if (!code) {
-               MonoTrampInfo *info;
-
-               code = mono_arch_create_monitor_exit_trampoline (&info, FALSE);
-               mono_tramp_info_register (info);
-       }
-
-       mono_trampolines_unlock ();
-#else
-       code = NULL;
-       g_assert_not_reached ();
-#endif
-       return code;
-}
  
 #ifdef MONO_ARCH_LLVM_SUPPORTED
 /*
@@ -1641,9 +1552,6 @@ static const char*tramp_names [MONO_TRAMPOLINE_NUM] = {
        "delegate",
        "restore_stack_prot",
        "generic_virtual_remoting",
-       "monitor_enter",
-       "monitor_enter_v4",
-       "monitor_exit",
        "vcall",
        "handler_block_guard"
 };
@@ -1705,7 +1613,7 @@ mini_get_single_step_trampoline (void)
 #ifdef MONO_ARCH_HAVE_SDB_TRAMPOLINES
                        MonoTrampInfo *info;
                        tramp = mono_arch_create_sdb_trampoline (TRUE, &info, FALSE);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
 #else
                        tramp = NULL;
                        g_assert_not_reached ();
@@ -1737,7 +1645,7 @@ mini_get_breakpoint_trampoline (void)
 #ifdef MONO_ARCH_HAVE_SDB_TRAMPOLINES
                        MonoTrampInfo *info;
                        tramp = mono_arch_create_sdb_trampoline (FALSE, &info, FALSE);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
 #else
                        tramp = NULL;
                        g_assert_not_reached ();