* ResourceReaderTest.cs: Add a little logic for finding
[mono.git] / mono / jit / trampoline.c
index fe0750b3068705eebd9651fff323f6ec467abd60..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"
-#include "message.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;
-       static MonoObject *(*invoke) (gpointer proxy, gpointer msg, 
-                                     MonoObject **exc, MonoArray **out_args) = NULL;
-
-       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 = mono_method_call_message_new (method, &first_arg);
-
-       /* fixme: make this domain dependent */
-       if (!invoke) {
-               MonoClass *klass;
-               int i;
-
-               klass = mono_defaults.real_proxy_class; 
-                      
-               for (i = 0; i < klass->method.count; ++i) {
-                       if (!strcmp ("PrivateInvoke", klass->methods [i]->name) &&
-                           klass->methods [i]->signature->param_count == 4) {
-                               invoke = arch_compile_method (klass->methods [i]);
-                               break;
-                       }
-               }
-       
-               g_assert (invoke);
-       }
-
-
-       res = invoke (this->rp, msg, &exc, &out_args);
-
-       if (exc)
-               mono_raise_exception ((MonoException *)exc);
-
-       mono_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:
@@ -122,15 +73,15 @@ get_unbox_trampoline (MonoMethod *m, gpointer addr)
  */
 static gpointer
 x86_magic_trampoline (int eax, int ecx, int edx, int esi, int edi, 
-                     int ebx, const guint8 *code, MonoMethod *m)
+                     int ebx, guint8 *code, MonoMethod *m)
 {
        guint8 reg;
        gint32 disp;
-       gpointer o;
+       char *o;
        gpointer addr;
 
        EnterCriticalSection (metadata_section);
-       addr = arch_compile_method (m);
+       addr = mono_compile_method (m);
        LeaveCriticalSection (metadata_section);
        g_assert (addr);
 
@@ -153,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 ();
                }
        }
@@ -205,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)
@@ -216,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);
-               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;
+               MonoMethod *nm;
+               
+               if (!method->addr && (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
+                       mono_lookup_pinvoke_call (method);
 
-       if ((code = g_hash_table_lookup (jit_code_hash, method))) {
-               mono_jit_stats.methods_lookups++;
-               return code;
+#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;
        }
 
-       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);
@@ -259,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) */
@@ -307,44 +257,13 @@ 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);
        }
 
-       if (method->klass->marshalbyref && method->signature->hasthis) {
-               int thispos = 4;
-
-               if (ISSTRUCT (method->signature->ret))
-                       thispos = 8;
-
-               code = buf = g_malloc (40);
-               /* load the this pointer */
-               x86_mov_reg_membase (buf, X86_EAX, X86_ESP, thispos, 4);
-               /* load the method pointer */
-               x86_push_imm (buf, method);
-               /* load vtable */
-               x86_mov_reg_membase (buf, X86_EAX, X86_EAX, 0, 4);
-               /* class = transparent proxy */
-               x86_alu_membase_imm (buf, X86_CMP, X86_EAX, 0, ((int)mono_defaults.transparent_proxy_class));
-               x86_branch8 (buf, X86_CC_EQ, 10, FALSE);
-
-               /* jump to normal code - we need a faster way to lookup that code */
-               x86_call_code (buf, arch_compile_method);
-               x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);
-               x86_jump_reg (buf, X86_EAX);
-               
-               /* call remoting invoke */
-               x86_call_code (buf, arch_remoting_invoke);
-               x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);
-               x86_ret (buf);
-
-               g_assert ((buf - code) <= 40);
-
-       } else {
-               code = buf = g_malloc (16);
-               x86_push_imm (buf, method);
-               x86_jump_code (buf, vc);
-               g_assert ((buf - code) <= 16);
-       }
+       code = buf = g_malloc (16);
+       x86_push_imm (buf, method);
+       x86_jump_code (buf, mono_generic_trampoline_code);
+       g_assert ((buf - code) <= 16);
 
        /* store trampoline address */
        method->info = code;
@@ -353,32 +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)
-{
-       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;
-
-       return code;
-}