#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:
*/
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);
*((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 ();
}
}
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)
/* 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);
/* 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) */
/* 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;
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;
-}