#define CREATE_STACK_SIZE (CREATE_LMF_OFFSET+2*sizeof(long)+sizeof(MonoLMF))
#define METHOD_SAVE_OFFSET S390_RET_ADDR_OFFSET-4
-/*------------------------------------------------------------------*/
-/* adapt to mini later... */
-/*------------------------------------------------------------------*/
-#define mono_jit_share_code (1)
-
/*------------------------------------------------------------------*/
/* Method-specific trampoline code fragment sizes */
/*------------------------------------------------------------------*/
/* T y p e d e f s */
/*------------------------------------------------------------------*/
-typedef enum {
- MONO_TRAMPOLINE_GENERIC,
- MONO_TRAMPOLINE_JUMP,
- MONO_TRAMPOLINE_CLASS_INIT
-} MonoTrampolineType;
-
/*========================= End of Typedefs ========================*/
/*------------------------------------------------------------------*/
/* P r o t o t y p e s */
/*------------------------------------------------------------------*/
-/*------------------------------------------------------------------*/
-/* Address of the generic trampoline code. This is used by the */
-/* debugger to check whether a method is a trampoline. */
-/*------------------------------------------------------------------*/
-guint8 *mono_generic_trampoline_code = NULL;
-
/*========================= End of Prototypes ======================*/
/*------------------------------------------------------------------*/
int this_pos = s390_r2;
start = addr;
- if ((method->klass->valuetype)) {
-// if ((method->klass->valuetype) &&
-// (method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
- if ((!method->signature->ret->byref) &&
- (MONO_TYPE_ISSTRUCT (method->signature->ret)))
- this_pos = s390_r3;
-
- start = code = g_malloc (28);
-
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, addr);
- s390_l (code, s390_r1, 0, s390_r13, 4);
- s390_ahi (code, this_pos, sizeof(MonoObject));
- s390_br (code, s390_r1);
-
- g_assert ((code - start) <= 28);
- }
+ if ((!mono_method_signature (method)->ret->byref) &&
+ (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)))
+ this_pos = s390_r3;
+
+ start = code = mono_global_codeman_reserve (28);
+
+ s390_basr (code, s390_r13, 0);
+ s390_j (code, 4);
+ s390_word (code, addr);
+ s390_l (code, s390_r1, 0, s390_r13, 4);
+ s390_ahi (code, this_pos, sizeof(MonoObject));
+ s390_br (code, s390_r1);
+
+ g_assert ((code - start) <= 28);
return start;
}
{
gpointer addr;
gint32 displace;
- int reg, base;
+ int reg;
+ guchar* base;
unsigned short opcode;
char *fname;
MonoJitInfo *codeJi,
if (code) {
/* The top bit needs to be ignored on S/390 */
- (guint32) code &= 0x7fffffff;
+ code = (guchar*)((guint32)code & 0x7fffffff);
fname = mono_method_full_name (method, TRUE);
codeJi = mono_jit_info_table_find (mono_domain_get(), code);
addrJi = mono_jit_info_table_find (mono_domain_get(), addr);
+ if (mono_method_same_domain (codeJi, addrJi)) {
+
+ opcode = *((unsigned short *) (code - 6));
+ switch (opcode) {
+ case 0x5810 :
+ /* This is a bras r14,r1 instruction */
+ code -= 4;
+ reg = *code >> 4;
+ displace = *((short *)code) & 0x0fff;
+ if (reg > 5)
+ base = *((guchar **) (sp + S390_REG_SAVE_OFFSET+
+ sizeof(int)*(reg-6)));
+ else
+ base = *((guchar **) (sp + CREATE_GR_OFFSET+
+ sizeof(int)*(reg-2)));
+
+ if ((method->klass->valuetype) &&
+ (!mono_aot_is_got_entry(code, base)))
+ addr = get_unbox_trampoline(method, addr);
- opcode = *((unsigned short *) (code - 6));
- switch (opcode) {
- case 0x5810 :
- /* This is a bras r14,r1 instruction */
- code -= 4;
- reg = *code >> 4;
- displace = *((short *)code) & 0x0fff;
- if (reg > 5)
- base = *((int *) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(reg-6)));
- else
- base = *((int *) (sp + CREATE_GR_OFFSET+
- sizeof(int)*(reg-2)));
- addr = get_unbox_trampoline(method, addr);
- if (mono_method_same_domain (codeJi, addrJi)) {
code = base + displace;
- s390_patch(code, addr);
- }
- break;
- case 0xc0e5 :
- /* This is the 'brasl' instruction */
- code -= 4;
- displace = ((gint32) addr - (gint32) (code - 2)) / 2;
- if (mono_method_same_domain (codeJi, addrJi)) {
- s390_patch (code, displace);
- mono_arch_flush_icache (code, 4);
- }
- break;
- default :
- g_error("Unable to patch instruction prior to %p",code);
+ if (mono_domain_owns_vtable_slot(mono_domain_get(),
+ code))
+ s390_patch(code, addr);
+ break;
+ case 0xc0e5 :
+ /* This is the 'brasl' instruction */
+ code -= 4;
+ displace = ((gint32) addr - (gint32) (code - 2)) / 2;
+ if (mono_method_same_domain (codeJi, addrJi)) {
+ s390_patch (code, displace);
+ mono_arch_flush_icache (code, 4);
+ }
+ break;
+ default :
+ g_error("Unable to patch instruction prior to %p",code);
+ }
}
}
/*------------------------------------------------------------------*/
/* */
-/* Name - create_trampoline_code */
+/* Name - mono_arch_create_trampoline_code */
/* */
/* Function - Create the designated type of trampoline according*/
/* to the 'tramp_type' parameter. */
/* */
/*------------------------------------------------------------------*/
-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, lmfOffset;
- 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 S/390 trampoline code. This
is the trampoline code common to all methods */
- code = buf = g_malloc(512);
+ code = buf = mono_global_codeman_reserve(512);
/*-----------------------------------------------------------
STEP 0: First create a non-standard function prologue with a
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;
}
MonoDomain *domain = mono_domain_get();
gint32 displace;
- tramp = create_trampoline_code (MONO_TRAMPOLINE_JUMP);
+ tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_JUMP);
mono_domain_lock (domain);
code = buf = mono_code_manager_reserve (domain->code_mp, METHOD_TRAMPOLINE_SIZE);
static guint8 *vc = NULL;
gint32 displace;
- 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)));
-
- vc = create_trampoline_code (MONO_TRAMPOLINE_GENERIC);
+ vc = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC);
/* This is the method-specific part of the trampoline. Its purpose is
to provide the generic part with the MonoMethod *method pointer. We'll
use r13 to keep that value, for instance. However, the generic part of
the trampoline relies on r11 having the same value it had before coming
here, so we must save it before. */
- code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
+ code = buf = mono_global_codeman_reserve(METHOD_TRAMPOLINE_SIZE);
s390_basr (buf, s390_r13, 0);
s390_j (buf, 4);
/* Sanity check */
g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
- method->info = code;
- mono_jit_stats.method_trampolines++;
-
return code;
}
{
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
- use r11 to keep that value, for instance. However, the generic part of
- the trampoline relies on r11 having the same value it had before coming
- here, so we must save it before. */
- code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
+ /*-----------------------------------------------------------*/
+ /* This is the method-specific part of the trampoline. Its */
+ /* purpose is to provide the generic part with the MonoMethod*/
+ /* *method pointer. We'll use r11 to keep that value, for */
+ /* instance. However, the generic part of the trampoline */
+ /* relies on r11 having the same value it had before coming */
+ /* here, so we must save it before. */
+ /*-----------------------------------------------------------*/
+ code = buf = mono_global_codeman_reserve(METHOD_TRAMPOLINE_SIZE);
s390_st (buf, s390_r14, 0, STK_BASE, S390_RET_ADDR_OFFSET);
s390_ahi (buf, STK_BASE, -S390_MINIMAL_STACK_SIZE);
{
guint8 *ptr, *buf;
- ptr = buf = g_malloc0 (16);
+ ptr = buf = mono_global_codeman_reserve (16);
s390_break (buf);
if (notification_address)
*notification_address = buf;