#include "mini.h"
#include "mini-ppc.h"
-typedef enum {
- MONO_TRAMPOLINE_GENERIC,
- MONO_TRAMPOLINE_JUMP,
- MONO_TRAMPOLINE_CLASS_INIT
-} MonoTrampolineType;
-
-/* adapt to mini later... */
-#define mono_jit_share_code (1)
-
-/*
- * 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:
* @m: method pointer
guint8 *code, *start;
int this_pos = 3;
- if (!m->signature->ret->byref && MONO_TYPE_ISSTRUCT (m->signature->ret))
+ if (!mono_method_signature (m)->ret->byref && MONO_TYPE_ISSTRUCT (mono_method_signature (m)->ret))
this_pos = 4;
start = code = g_malloc (20);
{
char *o = NULL;
gpointer addr;
+ MonoJitInfo *ji, *target_ji;
int reg, offset = 0;
addr = mono_compile_method(method);
return addr;
}
+ /* We can't trampoline across domains */
+ ji = mono_jit_info_table_find (mono_domain_get (), code);
+ target_ji = mono_jit_info_table_find (mono_domain_get (), addr);
+ if (!mono_method_same_domain (ji, target_ji))
+ return addr;
+
/* Locate the address of the method-specific trampoline. The call using
the vtable slot that took the processing flow to 'arch_create_jit_trampoline'
looks something like this:
/* Sanity check: instruction must be 'blrl' */
g_assert(*code == 0x4e800021);
-
+
+ /* the thunk-less direct call sequence: lis/ori/mtlr/blrl */
+ if ((code [-1] >> 26) == 31 && (code [-2] >> 26) == 24 && (code [-3] >> 26) == 15) {
+ ppc_patch ((char*)code, addr);
+ return addr;
+ }
+
/* OK, we're now at the 'blrl' instruction. Now walk backwards
till we get to a 'mtlr rA' */
for(; --code;) {
we won't have an object, but the actual pointer to the
valuetype as the this argument
*/
- if (method->klass->valuetype)
+ if (method->klass->valuetype && !mono_aot_is_got_entry (code, o))
addr = get_unbox_trampoline (method, addr);
o += offset;
- *((gpointer *)o) = addr;
+ if (mono_aot_is_got_entry (code, o) || mono_domain_owns_vtable_slot (mono_domain_get (), o))
+ *((gpointer *)o) = addr;
return addr;
}
* linkage area
* -------------------
*/
-static guchar*
-create_trampoline_code (MonoTrampolineType tramp_type)
+guchar*
+mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
{
guint8 *buf, *code = NULL;
- static guint8* generic_jump_trampoline = NULL;
- static guint8 *generic_class_init_trampoline = NULL;
int i, offset;
- switch (tramp_type) {
- case MONO_TRAMPOLINE_GENERIC:
- if (mono_generic_trampoline_code)
- return mono_generic_trampoline_code;
- break;
- case MONO_TRAMPOLINE_JUMP:
- if (generic_jump_trampoline)
- return generic_jump_trampoline;
- break;
- case MONO_TRAMPOLINE_CLASS_INIT:
- if (generic_class_init_trampoline)
- return generic_class_init_trampoline;
- break;
- }
-
if(!code) {
/* Now we'll create in 'buf' the PowerPC trampoline code. This
is the trampoline code common to all methods */
g_assert ((buf - code) <= 512);
}
- switch (tramp_type) {
- case MONO_TRAMPOLINE_GENERIC:
- mono_generic_trampoline_code = code;
- break;
- case MONO_TRAMPOLINE_JUMP:
- generic_jump_trampoline = code;
- break;
- case MONO_TRAMPOLINE_CLASS_INIT:
- generic_class_init_trampoline = code;
- break;
- }
-
return code;
}
guint8 *tramp;
MonoDomain* domain = mono_domain_get ();
- tramp = create_trampoline_code (MONO_TRAMPOLINE_JUMP);
+ tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_JUMP);
return create_specific_tramp (method, tramp, domain);
}
guint8 *tramp;
MonoJitInfo *ji;
MonoDomain* domain = mono_domain_get ();
+ gpointer code_start;
- /* previously created trampoline code */
- if (method->info)
- return method->info;
-
- if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
- return mono_arch_create_jit_trampoline (mono_marshal_get_synchronized_wrapper (method));
-
- tramp = create_trampoline_code (MONO_TRAMPOLINE_GENERIC);
- /* FIXME: should pass the domain down tot his function */
+ tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC);
+ /* FIXME: should pass the domain down to this function */
ji = create_specific_tramp (method, tramp, domain);
- /* Store trampoline address */
- method->info = ji->code_start;
- return ji->code_start;
+ code_start = ji->code_start;
+ g_free (ji);
+
+ return code_start;
}
/**
{
guint8 *code, *buf, *tramp;
- tramp = create_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
+ tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
/* This is the method-specific part of the trampoline. Its purpose is
to provide the generic part with the MonoMethod *method pointer. We'll
if (notification_address)
*notification_address = buf;
ppc_blr (buf);
+ mono_arch_flush_icache (ptr, buf - ptr);
return ptr;
}