* ResourceReaderTest.cs: Add a little logic for finding
[mono.git] / mono / jit / trampoline.c
index 8b0a175346433fd04ef9444227e04607bc05a407..5bbfd7fb3d3d690d3c5998e2c3cfc2ad95365d36 100644 (file)
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/arch/x86/x86-codegen.h>
+#include <mono/metadata/mono-debug-debugger.h>
 
 #include "jit.h"
 #include "codegen.h"
 
-static void
-arch_remoting_invoke (MonoMethod *method, gpointer ip, gpointer first_arg)
-{
-       MonoMethodSignature *sig = method->signature;
-       MonoMethodMessage *msg;
-       MonoTransparentProxy *this;
-       MonoObject *res, *exc;
-       MonoArray *out_args;
-       int this_pos = 0;
-
-       //printf ("REMOTING %s.%s:%s\n", method->klass->name_space, method->klass->name,
-       //method->name);
-
-       if (ISSTRUCT (sig->ret))
-               this_pos += 4;
-
-       this = *(MonoTransparentProxy **)(((char *)&first_arg) + this_pos);
-
-       g_assert (((MonoObject *)this)->vtable->klass == mono_defaults.transparent_proxy_class);
-
-       msg = arch_method_call_message_new (method, &first_arg, NULL, NULL, NULL);
-
-       res = mono_remoting_invoke ((MonoObject *)this->rp, msg, &exc, &out_args);
-
-       if (exc)
-               mono_raise_exception ((MonoException *)exc);
-
-       arch_method_return_message_restore (method, &first_arg, res, out_args);
-
-       /* WARNING: do not write any code here, because that would destroy 
-        * the return value 
-        */
-}
+/*
+ * Address of the x86 trampoline code.  This is used by the debugger to check
+ * whether a method is a trampoline.
+ */
+guint8 *mono_generic_trampoline_code = NULL;
 
 /*
  * get_unbox_trampoline:
@@ -108,7 +81,7 @@ x86_magic_trampoline (int eax, int ecx, int edx, int esi, int edi,
        gpointer addr;
 
        EnterCriticalSection (metadata_section);
-       addr = arch_compile_method (m);
+       addr = mono_compile_method (m);
        LeaveCriticalSection (metadata_section);
        g_assert (addr);
 
@@ -131,8 +104,8 @@ x86_magic_trampoline (int eax, int ecx, int edx, int esi, int edi,
                        *((guint32*)(code + 2)) = (guint)addr - ((guint)code + 1) - 5; 
                        return addr;
                } else {
-                       printf ("%x %x %x %x %x %x \n", code [0], code [1], code [2], code [3],
-                               code [4], code [5]);
+                       printf ("Invalid trampoline sequence: %x %x %x %x %x %x %x\n", code [0], code [1], code [2], code [3],
+                               code [4], code [5], code [6]);
                        g_assert_not_reached ();
                }
        }
@@ -183,10 +156,7 @@ x86_magic_trampoline (int eax, int ecx, int edx, int esi, int edi,
 gpointer
 arch_create_jit_trampoline (MonoMethod *method)
 {
-       MonoDomain *domain = mono_domain_get ();
        guint8 *code, *buf;
-       static guint8 *vc = NULL;
-       GHashTable *jit_code_hash;
 
        /* previously created trampoline code */
        if (method->info)
@@ -194,31 +164,33 @@ arch_create_jit_trampoline (MonoMethod *method)
 
        /* we immediately compile runtime provided functions */
        if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
-               method->info = arch_compile_method (method);
+               method->info = mono_compile_method (method);
                return method->info;
        }
 
        /* icalls use method->addr */
        if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
            (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
-               method->info = arch_create_native_wrapper (method);
+               MonoMethod *nm;
+               
+               if (!method->addr && (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
+                       mono_lookup_pinvoke_call (method);
+
+#ifdef MONO_USE_EXC_TABLES
+               if (mono_method_blittable (method)) {
+                       method->info = method->addr;
+               } else {
+#endif
+                       nm = mono_marshal_get_native_wrapper (method);
+                       method->info = mono_compile_method (nm);
+#ifdef MONO_USE_EXC_TABLES
+               }
+#endif
                return method->info;
        }
 
-       /* check if we already have JITed code */
-       if (mono_jit_share_code)
-               jit_code_hash = mono_root_domain->jit_code_hash;
-       else
-               jit_code_hash = domain->jit_code_hash;
-
-       if ((code = g_hash_table_lookup (jit_code_hash, method))) {
-               mono_jit_stats.methods_lookups++;
-               return code;
-       }
-
-       if (!vc) {
-               vc = buf = g_malloc (256);
-
+       if (!mono_generic_trampoline_code) {
+               mono_generic_trampoline_code = buf = g_malloc (256);
                /* save caller save regs because we need to do a call */ 
                x86_push_reg (buf, X86_EDX);
                x86_push_reg (buf, X86_EAX);
@@ -237,7 +209,7 @@ arch_create_jit_trampoline (MonoMethod *method)
                /* save method info */
                x86_push_membase (buf, X86_ESP, 32);
                /* get the address of lmf for the current thread */
-               x86_call_code (buf, arch_get_lmf_addr);
+               x86_call_code (buf, mono_get_lmf_addr);
                /* push lmf */
                x86_push_reg (buf, X86_EAX); 
                /* push *lfm (previous_lmf) */
@@ -285,12 +257,12 @@ arch_create_jit_trampoline (MonoMethod *method)
                /* call the compiled method */
                x86_jump_reg (buf, X86_EAX);
 
-               g_assert ((buf - vc) <= 256);
+               g_assert ((buf - mono_generic_trampoline_code) <= 256);
        }
 
        code = buf = g_malloc (16);
        x86_push_imm (buf, method);
-       x86_jump_code (buf, vc);
+       x86_jump_code (buf, mono_generic_trampoline_code);
        g_assert ((buf - code) <= 16);
 
        /* store trampoline address */
@@ -300,43 +272,3 @@ arch_create_jit_trampoline (MonoMethod *method)
 
        return code;
 }
-
-/* arch_create_remoting_trampoline:
- * @method: pointer to the method info
- *
- * Creates a trampoline which calls the remoting functions. This
- * is used in the vtable of transparent proxies.
- * 
- * Returns: a pointer to the newly created code 
- */
-gpointer
-arch_create_remoting_trampoline (MonoMethod *method)
-{
-       MonoJitInfo *ji;
-       guint8 *code, *buf;
-
-       if (method->remoting_tramp)
-               return method->remoting_tramp;
-       
-       code = buf = g_malloc (16);
-       x86_push_imm (buf, method);
-       x86_call_code (buf, arch_remoting_invoke);
-       x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);
-       x86_ret (buf);
-       
-       g_assert ((buf - code) <= 16);
-
-       method->remoting_tramp = code;
-
-       /* we store a jit info, so that mono_delegate_ctor
-        * is able to find a method info */
-       ji = mono_mempool_alloc0 (mono_root_domain->mp, sizeof (MonoJitInfo));
-       ji->method = method;
-       ji->code_start = code;
-       ji->code_size = buf - code;
-       ji->used_regs = 0;
-       ji->num_clauses = 0;
-       mono_jit_info_table_add (mono_root_domain, ji);
-
-       return code;
-}