Author: zoltan
Date: 2007-10-17 14:56:35 -0400 (Wed, 17 Oct 2007)
New Revision: 87704
Modified:
trunk/mono/mono/mini/ChangeLog
trunk/mono/mono/mini/inssel.brg
trunk/mono/mono/mini/mini-ia64.c
trunk/mono/mono/mini/mini-ia64.h
Log:
2007-10-17 Zoltan Varga <[EMAIL PROTECTED]>
* inssel.brg (mini_emit_virtual_call): Fix the computation of
ins->inst_offset on
64 bit platforms.
* mini-ia64.h mini-ia64.c: Add support for IMT.
Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog 2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/ChangeLog 2007-10-17 18:56:35 UTC (rev 87704)
@@ -1,5 +1,10 @@
2007-10-17 Zoltan Varga <[EMAIL PROTECTED]>
+ * inssel.brg (mini_emit_virtual_call): Fix the computation of
ins->inst_offset on
+ 64 bit platforms.
+
+ * mini-ia64.h mini-ia64.c: Add support for IMT.
+
* mini-x86.c (mono_arch_emit_prolog): Increase the size allocated for
the
prolog. Fixes #331958.
Modified: trunk/mono/mono/mini/inssel.brg
===================================================================
--- trunk/mono/mono/mini/inssel.brg 2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/inssel.brg 2007-10-17 18:56:35 UTC (rev 87704)
@@ -1814,7 +1814,7 @@
guint32 imt_slot = mono_method_get_imt_slot (method);
emit_imt_argument (cfg, (MonoCallInst*)tree);
slot_reg = vtable_reg;
- tree->inst_offset = (imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P;
+ tree->inst_offset = ((gint32)imt_slot - MONO_IMT_SIZE) *
SIZEOF_VOID_P;
#else
slot_reg = mono_regstate_next_int (cfg->rs);
mini_emit_load_intf_reg_vtable (cfg, slot_reg, vtable_reg,
method->klass);
Modified: trunk/mono/mono/mini/mini-ia64.c
===================================================================
--- trunk/mono/mono/mini/mini-ia64.c 2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/mini-ia64.c 2007-10-17 18:56:35 UTC (rev 87704)
@@ -2803,7 +2803,11 @@
case OP_LCALL_MEMBASE:
case OP_VCALL_MEMBASE:
case OP_VOIDCALL_MEMBASE:
- case OP_CALL_MEMBASE:
+ case OP_CALL_MEMBASE: {
+ MonoCallInst *call = (MonoCallInst*)ins;
+ CallInfo *cinfo;
+ int out_reg;
+
/*
* There are no membase instructions on ia64, but we
can't
* lower this since get_vcall_slot_addr () needs to
decode it.
@@ -2817,6 +2821,26 @@
ia64_add (code, IA64_R8, GP_SCRATCH_REG,
ins->sreg1);
}
+ if (call->method && ins->inst_offset < 0) {
+ /*
+ * This is a possible IMT call so save the IMT
method in a global
+ * register where mono_arch_find_imt_method ()
and its friends can access
+ * it.
+ */
+ ia64_movl (code, IA64_R9, call->method);
+ }
+
+ /*
+ * mono_arch_find_this_arg () needs to find the this
argument in a global
+ * register.
+ */
+ cinfo = get_call_info (NULL, call->signature, FALSE);
+ out_reg = cfg->arch.reg_out0;
+ if (cinfo->ret.storage == ArgValuetypeAddrInIReg)
+ out_reg ++;
+ g_free (cinfo);
+ ia64_mov (code, IA64_R10, out_reg);
+
ia64_begin_bundle (code);
ia64_codegen_set_one_ins_per_bundle (code, TRUE);
@@ -2836,6 +2860,7 @@
code = emit_move_return_value (cfg, ins, code);
break;
+ }
case OP_JMP: {
/*
* Keep in sync with the code in emit_epilog.
@@ -4608,6 +4633,104 @@
}
}
+
+#ifdef MONO_ARCH_HAVE_IMT
+
+/*
+ * LOCKING: called with the domain lock held
+ */
+gpointer
+mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
MonoIMTCheckItem **imt_entries, int count)
+{
+ int i;
+ int size = 0;
+ guint8 *start, *buf;
+ Ia64CodegenState code;
+
+ size = count * 256;
+ buf = g_malloc0 (size);
+ ia64_codegen_init (code, buf);
+
+ for (i = 0; i < count; ++i) {
+ MonoIMTCheckItem *item = imt_entries [i];
+ ia64_begin_bundle (code);
+ item->code_target = (guint8*)code.buf + code.nins;
+ if (item->is_equals) {
+ if (item->check_target_idx) {
+ if (!item->compare_done) {
+ ia64_movl (code, IA64_R8, item->method);
+ ia64_cmp_eq (code, 6, 7, IA64_R9,
IA64_R8);
+ }
+ item->jmp_code = (guint8*)code.buf + code.nins;
+ ia64_br_cond_pred (code, 7, 0);
+
+ ia64_movl (code, IA64_R8, &(vtable->vtable
[item->vtable_slot]));
+ ia64_ld8 (code, IA64_R8, IA64_R8);
+ ia64_mov_to_br (code, IA64_B6, IA64_R8);
+ ia64_br_cond_reg (code, IA64_B6);
+ } else {
+ /* enable the commented code to assert on wrong
method */
+#if ENABLE_WRONG_METHOD_CHECK
+ g_assert_not_reached ();
+#endif
+ ia64_movl (code, IA64_R8, &(vtable->vtable
[item->vtable_slot]));
+ ia64_ld8 (code, IA64_R8, IA64_R8);
+ ia64_mov_to_br (code, IA64_B6, IA64_R8);
+ ia64_br_cond_reg (code, IA64_B6);
+#if ENABLE_WRONG_METHOD_CHECK
+ g_assert_not_reached ();
+#endif
+ }
+ } else {
+ ia64_movl (code, IA64_R8, item->method);
+ ia64_cmp_geu (code, 6, 7, IA64_R9, IA64_R8);
+ item->jmp_code = (guint8*)code.buf + code.nins;
+ ia64_br_cond_pred (code, 6, 0);
+ }
+ }
+ /* patch the branches to get to the target items */
+ for (i = 0; i < count; ++i) {
+ MonoIMTCheckItem *item = imt_entries [i];
+ if (item->jmp_code) {
+ if (item->check_target_idx) {
+ ia64_patch (item->jmp_code, imt_entries
[item->check_target_idx]->code_target);
+ }
+ }
+ }
+
+ ia64_codegen_close (code);
+ g_assert (code.buf - buf <= size);
+
+ size = code.buf - buf;
+ start = mono_code_manager_reserve (domain->code_mp, size);
+ memcpy (start, buf, size);
+
+ mono_arch_flush_icache (start, size);
+
+ mono_stats.imt_thunks_size += size;
+
+ return start;
+}
+
+MonoMethod*
+mono_arch_find_imt_method (gpointer *regs, guint8 *code)
+{
+ return regs [IA64_R9];
+}
+
+MonoObject*
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+{
+ return regs [IA64_R10];
+}
+
+void
+mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call)
+{
+ /* Done by the implementation of the CALL_MEMBASE opcodes */
+}
+#endif
+
MonoInst*
mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod,
MonoMethodSignature *fsig, MonoInst **args)
{
Modified: trunk/mono/mono/mini/mini-ia64.h
===================================================================
--- trunk/mono/mono/mini/mini-ia64.h 2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/mini-ia64.h 2007-10-17 18:56:35 UTC (rev 87704)
@@ -183,5 +183,6 @@
#define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE 1
#define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1
#define MONO_ARCH_HAVE_CREATE_VARS 1
+#define MONO_ARCH_HAVE_IMT 1
#endif /* __MONO_MINI_IA64_H__ */
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches