* ResourceReaderTest.cs: Add a little logic for finding
[mono.git] / mono / jit / trampoline.c
index 44aa461bdcd1da9d69691b219bbbda77c5666006..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"
-/**
- * mono_remoting_invoke:
- * @real_proxy: pointer to a RealProxy object
- * @msg: The MonoMethodMessage to execute
- * @exc: used to store exceptions
- * @out_args: used to store output arguments
- *
- * This is used to call RealProxy::Invoke(). RealProxy::Invoke() returns an
- * IMessage interface and it is not trivial to extract results from there. So
- * we call an helper method PrivateInvoke instead of calling
- * RealProxy::Invoke() directly.
- *
- * Returns: the result object.
- */
-MonoObject *
-mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, 
-                     MonoObject **exc, MonoArray **out_args)
-{
-       static MonoObject *(*invoke) (gpointer, gpointer, MonoObject **, MonoArray **) = NULL;
-
-       /* 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);
-       }
-
-       return invoke (real_proxy, msg, exc, out_args);
-}
-
-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);
-
-       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:
@@ -148,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);
 
@@ -171,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 ();
                }
        }
@@ -223,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)
@@ -234,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);
@@ -277,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) */
@@ -325,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 */
@@ -340,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;
-}