[Mono-list] jit pacth: bug fixes

Dietmar Maurer dietmar@ximian.com
05 Nov 2001 16:30:17 +0100


20 out of 33 tests in mono/tests are working.


Index: mono/dis/main.c
===================================================================
RCS file: /cvs/public/mono/mono/dis/main.c,v
retrieving revision 1.41
diff -u -r1.41 main.c
--- mono/dis/main.c	2001/10/15 09:50:02	1.41
+++ mono/dis/main.c	2001/11/05 11:29:05
@@ -32,10 +32,10 @@
 
 int dump_table = -1;
 
-gpointer arch_compile_method (MonoMethod *method);
+gpointer arch_create_jit_trampoline (MonoMethod *method, gboolean virtual);
 
 gpointer 
-arch_compile_method (MonoMethod *method)
+arch_create_jit_trampoline (MonoMethod *method, gboolean virtual)
 {
 	return method;
 }
Index: mono/interpreter/interp.c
===================================================================
RCS file: /cvs/public/mono/mono/interpreter/interp.c,v
retrieving revision 1.90
diff -u -r1.90 interp.c
--- mono/interpreter/interp.c	2001/11/05 06:22:05	1.90
+++ mono/interpreter/interp.c	2001/11/05 11:29:05
@@ -86,10 +86,10 @@
 
 typedef void (*ICallMethod) (MonoInvocation *frame);
 
-gpointer arch_compile_method (MonoMethod *method);
+gpointer arch_create_jit_trampoline (MonoMethod *method, gboolean virtual);
 
 gpointer 
-arch_compile_method (MonoMethod *method)
+arch_create_jit_trampoline (MonoMethod *method, gboolean virtual)
 {
 	return method;
 }
Index: mono/jit/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/jit/ChangeLog,v
retrieving revision 1.33
diff -u -r1.33 ChangeLog
--- mono/jit/ChangeLog	2001/11/03 05:56:29	1.33
+++ mono/jit/ChangeLog	2001/11/05 11:29:05
@@ -1,3 +1,9 @@
+2001-11-05  Dietmar Maurer  <dietmar@ximian.com>
+
+	* testjit.c: bug fixes.
+
+	* emit-x86.c (leave_method): print result values
+
 2001-11-03  Dietmar Maurer  <dietmar@ximian.com>
 
 	* emit-x86.c (enter_method): new debugging code
Index: mono/jit/emit-x86.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/emit-x86.c,v
retrieving revision 1.11
diff -u -r1.11 emit-x86.c
--- mono/jit/emit-x86.c	2001/11/03 05:56:29	1.11
+++ mono/jit/emit-x86.c	2001/11/05 11:29:05
@@ -30,13 +30,50 @@
 }
 
 static void
-leave_method (MonoMethod *method)
+leave_method (MonoMethod *method, int edx, int eax, double test)
 {
-	printf ("LEAVE: %s.%s::%s\n", method->klass->name_space,
-		method->klass->name, method->name);
+	switch (method->signature->ret->type) {
+	case MONO_TYPE_VOID:
+		printf ("LEAVE: %s.%s::%s\n", method->klass->name_space,
+			method->klass->name, method->name);
+		break;
+	case MONO_TYPE_BOOLEAN:
+	case MONO_TYPE_CHAR:
+	case MONO_TYPE_I1:
+	case MONO_TYPE_U1:
+	case MONO_TYPE_I2:
+	case MONO_TYPE_U2:
+	case MONO_TYPE_I4:
+	case MONO_TYPE_U4:
+	case MONO_TYPE_I:
+	case MONO_TYPE_U:
+		printf ("LEAVE: %s.%s::%s EAX=%d\n", method->klass->name_space,
+			method->klass->name, method->name, eax);
+		break;
+	case MONO_TYPE_STRING:
+	case MONO_TYPE_PTR:
+	case MONO_TYPE_CLASS:
+	case MONO_TYPE_OBJECT:
+	case MONO_TYPE_FNPTR:
+	case MONO_TYPE_ARRAY:
+	case MONO_TYPE_SZARRAY:
+		printf ("LEAVE: %s.%s::%s EAX=%p\n", method->klass->name_space,
+			method->klass->name, method->name, (gpointer)eax);
+		break;
+	case MONO_TYPE_I8:
+		printf ("LEAVE: %s.%s::%s EAX=%d EDX=%d\n", method->klass->name_space,
+			method->klass->name, method->name, eax, edx);
+		break;
+	case MONO_TYPE_R8:
+		printf ("LEAVE: %s.%s::%s FP=%f\n", method->klass->name_space,
+			method->klass->name, method->name, test);
+		break;
+	default:
+		printf ("LEAVE: %s.%s::%s (unknown return type)\n", method->klass->name_space,
+			method->klass->name, method->name);
+	}
 }
 
-
 /**
  * arch_emit_prologue:
  * @s: pointer to status information
@@ -78,6 +115,9 @@
 arch_emit_epilogue (MonoFlowGraph *cfg)
 {
 	if (mono_jit_trace_calls) {
+		x86_fld_reg (cfg->code, 0);
+		x86_alu_reg_imm (cfg->code, X86_SUB, X86_ESP, 8);
+		x86_fst_membase (cfg->code, X86_ESP, 0, TRUE, TRUE);
 		x86_push_reg (cfg->code, X86_EAX);
 		x86_push_reg (cfg->code, X86_EDX);
 		x86_push_imm (cfg->code, cfg->method);
@@ -85,6 +125,7 @@
 		x86_alu_reg_imm (cfg->code, X86_ADD, X86_ESP, 4);
 		x86_pop_reg (cfg->code, X86_EDX);
 		x86_pop_reg (cfg->code, X86_EAX);
+		x86_alu_reg_imm (cfg->code, X86_ADD, X86_ESP, 8);
 	}
 
 	if (mono_regset_reg_used (cfg->rs, X86_EDI))
@@ -100,23 +141,36 @@
 	x86_ret (cfg->code);
 }
 
+static void
+arch_vtable_trampoline ()
+{
+	//guint8 *code, *buf;
+
+	g_assert_not_reached ();
+}
+
+
 /**
  * arch_create_jit_trampoline:
  * @method: pointer to the method info
  *
  * Creates a trampoline function for method. If the created
- * code is called then it first starts JIT compilation of method,
+ * code is called it first starts JIT compilation of method,
  * and then calls the newly created method. I also replaces the
- * address in method->addr with the result of the JIT compilation
- * step.
+ * address in method->addr with the result of the JIT 
+ * compilation step.
  * 
  * Returns: a pointer to the newly created code 
  */
 gpointer
-arch_create_jit_trampoline (MonoMethod *method)
+arch_create_jit_trampoline (MonoMethod *method, gboolean vtable)
 {
 	guint8 *code, *buf;
 
+/*
+	if (vtable)
+		return arch_vtable_trampoline; 
+*/
 	if (method->addr)
 		return method->addr;
 
@@ -129,11 +183,19 @@
 	x86_call_code (buf, arch_compile_method);
 
 	/* free the allocated code buffer */
+	/* unfortunately this does not work, because we store the
+	 * trampoline in various places (for example the vtable of classes, 
+	 * and vtables are copied to inherited classes, there may be also 
+	 * several references in compiled code) - so we dont 
+	 * know how many references to the trampoline exists :-(
+	 */
+	/*
 	x86_push_reg (buf, X86_EAX);
 	x86_push_imm (buf, code);
 	x86_call_code (buf, g_free);
 	x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);
 	x86_pop_reg (buf, X86_EAX);
+	*/
 
 	x86_leave (buf);
 
@@ -394,6 +456,9 @@
 	g_assert (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL));
 	g_assert (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL));
 
+	//g_assert (!method->addr);
+
+	printf ("Start JIT compilation %p %p\n", method, method->addr);
 	printf ("Start JIT compilation of %s.%s:%s\n", method->klass->name_space,
 		method->klass->name, method->name);
 
@@ -439,6 +504,9 @@
 	mono_cfg_free (cfg);
 
 	mono_mempool_destroy (mp);
+
+	printf ("END JIT compilation of %s.%s:%s %p %p\n", method->klass->name_space,
+		method->klass->name, method->name, method, method->addr);
 
 	return method->addr;
 }
Index: mono/jit/jit.h
===================================================================
RCS file: /cvs/public/mono/mono/jit/jit.h,v
retrieving revision 1.8
diff -u -r1.8 jit.h
--- mono/jit/jit.h	2001/11/03 05:56:29	1.8
+++ mono/jit/jit.h	2001/11/05 11:29:05
@@ -91,7 +91,7 @@
 arch_compile_method        (MonoMethod *method);
 
 gpointer
-arch_create_jit_trampoline (MonoMethod *method);
+arch_create_jit_trampoline (MonoMethod *method, gboolean virtual);
 
 /* some handy debugging functions */
 
Index: mono/jit/testjit.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/testjit.c,v
retrieving revision 1.35
diff -u -r1.35 testjit.c
--- mono/jit/testjit.c	2001/11/03 05:56:29	1.35
+++ mono/jit/testjit.c	2001/11/05 11:29:06
@@ -641,6 +641,10 @@
 		t = ctree_dup_address (mp, s->left);
 		t->svt = VAL_I32;
 		return mono_ctree_new (mp, MB_TERM_LDIND_I4, t, NULL);
+	case MB_TERM_LDIND_U4:
+		t = ctree_dup_address (mp, s->left);
+		t->svt = VAL_I32;
+		return mono_ctree_new (mp, MB_TERM_LDIND_U4, t, NULL);
 	case MB_TERM_STIND_I8:
 	case MB_TERM_LDIND_I8:
 		t = ctree_dup_address (mp, s->left);
@@ -697,7 +701,7 @@
 		if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && 
 		    (strcmp (".cctor", method->name) == 0)) {
 	
-			cctor = arch_create_jit_trampoline (method);
+			cctor = arch_compile_method (method);
 			cctor ();
 			return;
 		}
@@ -809,14 +813,6 @@
 		case CEE_NOT:
 		case CEE_DUP:
 		case CEE_POP:
-		case CEE_CONV_U1: 
-		case CEE_CONV_I1:
-		case CEE_CONV_U2: 
-		case CEE_CONV_I2: 
-		case CEE_CONV_I: 
-		case CEE_CONV_I4:
-		case CEE_CONV_I8: 
-		case CEE_CONV_R8:
 		case CEE_ADD:
 		case CEE_SUB:
 		case CEE_AND:
@@ -869,6 +865,1_ @@
 		case CEE_LDELEM_R4:
 		case CEE_LDELEM_R8:
 		case CEE_LDELEM_REF:
+		case CEE_CONV_I1:
+		case CEE_CONV_U1:
+		case CEE_CONV_I2:
+		case CEE_CONV_U2:
+		case CEE_CONV_I:
+		case CEE_CONV_U:
+		case CEE_CONV_I4:
+		case CEE_CONV_U4:
+		case CEE_CONV_I8:
+		case CEE_CONV_U8:
+		case CEE_CONV_R4:
+		case CEE_CONV_R8:
 			ip++;
 			break;
 		case CEE_RET:
@@ -1506,9 +1514,6 @@
 
 			cm = mono_get_method (image, token, NULL);
 			g_assert (cm);
-
-			if (!cm->addr)
-				cm->addr = arch_create_jit_trampoline (cm);
 			
 			if ((cm->flags & METHOD_ATTRIBUTE_FINAL) ||
 			    !(cm->flags & METHOD_ATTRIBUTE_VIRTUAL))
@@ -1549,24 +1554,33 @@
 				sp = sp - nargs;
 			}
 
+			printf ("MINFO %s.%s::%s %d %d\n", cm->klass->name_space, 
+				cm->klass->name, cm->name, cm->flags & METHOD_ATTRIBUTE_VIRTUAL, virtual);
+ 
 			if (virtual) {
 				t2 = ctree_create_dup (mp, this);
-
+			       
 				if (!cm->klass->metadata_inited)
 					mono_class_metadata_init (cm->klass);
 
 				if (cm->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
-					t2 = mono_ctree_new (mp, MB_TERM_INTF_ADDR, t1, NULL);
+					t2 = mono_ctree_new (mp, MB_TERM_INTF_ADDR, t2, NULL);
 					t2->data.i = cm->klass->interface_id << 2;
-					printf ("SLOT %s %d %d\n", cm->name, cm->klass->metadata_inited, cm->slot);
+					printf ("SLOT %s.%s::%s %d %d\n", cm->klass->name_space, 
+						cm->klass->name, cm->name, cm->klass->metadata_inited, 
+						cm->slot);
 					t2->size = cm->slot << 2;
 				} else {
-					t2 = mono_ctree_new (mp, MB_TERM_VFUNC_ADDR, t1, NULL);
+					t2 = mono_ctree_new (mp, MB_TERM_VFUNC_ADDR, t2, NULL);
 					t2->data.i = cm->slot << 2;
 				}
 			} else {
+				if (!cm->addr)
+					cm->addr = arch_create_jit_trampoline (cm, FALSE);
+
 				t2 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
 				t2->data.p = (char *)cm + G_STRUCT_OFFSET (MonoMethod, addr);
+
 			}
 
 			if (nargs) {
@@ -2006,6 +2020,8 @@
 			break;
 		}
 		case CEE_CONV_I: 
+		case CEE_CONV_U: 
+		case CEE_CONV_U4: 
 		case CEE_CONV_I4: {
 			++ip;
 			sp--;
@@ -2142,7 +2158,7 @@
 	} else {
 		MonoMainIntVoid mfunc;
 
-		mfunc = arch_create_jit_trampoline (method);
+		mfunc = arch_compile_method (method);
 		res = mfunc ();
 	}
 	
Index: mono/jit/x86.brg
===================================================================
RCS file: /cvs/public/mono/mono/jit/x86.brg,v
retrieving revision 1.28
diff -u -r1.28 x86.brg
--- mono/jit/x86.brg	2001/11/03 05:56:29	1.28
+++ mono/jit/x86.brg	2001/11/05 11:29:06
@@ -136,6 +136,11 @@
 	tree->data.ainfo.amode = AMImmediate;
 }
 
+acon: ADD (ADDR_G, CONST_I4) {
+	tree->data.ainfo.offset = (unsigned)tree->left->data.p + tree->right->data.i;
+	tree->data.ainfo.amode = AMImmediate;
+}
+
 base: acon
 
 base: reg {
@@ -158,7 +163,7 @@
 
 index: reg {
 	tree->data.ainfo.offset = 0;
-	tree->data.ainfo.indexreg = tree->left->reg1;
+	tree->data.ainfo.indexreg = tree->reg1;
 	tree->data.ainfo.shift = 0;
 	tree->data.ainfo.amode = AMIndex;
 }
@@ -1390,6 +1395,16 @@
 	x86_fild (s->code, tree->left->left->data.p, FALSE);
 }
 
+freg: CONV_R8 (reg) {
+	/* I found no direct way to move an integer register to 
+	 * the floating point stack, so we need to store the register
+	 * to memory
+	 */
+	x86_push_reg (s->code, tree->left->reg1);
+	x86_fild_membase (s->code, X86_ESP, 0, FALSE);
+	x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
+}
+
 freg: CONST_R4 {
 	x86_fld (s->code, tree->data.p, FALSE);
 }
@@ -1530,6 +1545,30 @@
 	default:
 		g_assert_not_reached ();
 	}
+
+	if (tree->size)
+		x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
+}
+
+freg: CALL_R8 (INTF_ADDR (reg)) {
+	int reg1 = tree->left->left->reg1;
+
+	x86_mov_reg_membase (s->code, reg1, reg1, 0, 4);
+	x86_mov_reg_membase (s->code, reg1, reg1, 
+	        G_STRUCT_OFFSET (MonoClass, interface_offsets), 4);
+	x86_mov_reg_membase (s->code, reg1, reg1, tree->left->data.i, 4);
+	x86_call_membase (s->code, reg1, tree->left->size);
+
+	if (tree->size)
+		x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
+}
+
+freg: CALL_R8 (VFUNC_ADDR (reg)) {
+	int reg1 = tree->left->left->reg1;
+
+	x86_mov_reg_membase (s->code, reg1, reg1, 0, 4);
+	x86_call_membase (s->code, reg1, 
+	        G_STRUCT_OFFSET (MonoClass, vtable + tree->left->data.i));
 
 	if (tree->size)
 		x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
Index: mono/metadata/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/metadata/ChangeLog,v
retrieving revision 1.80
diff -u -r1.80 ChangeLog
--- mono/metadata/ChangeLog	2001/11/05 06:22:04	1.80
+++ mono/metadata/ChangeLog	2001/11/05 11:29:06
@@ -1,3 +1,7 @@
+2001-11-05  Dietmar Maurer  <dietmar@ximian.com>
+
+	* class.c (mono_class_metadata_init): create a trampoline for all
+	virtual functions instead of actually compiling them.
 
 Fri Nov 2 19:37:51 CET 2001 Paolo Molaro <lupus@ximian.com>
 
Index: mono/metadata/class.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/class.c,v
retrieving revision 1.46
diff -u -r1.46 class.c
--- mono/metadata/class.c	2001/11/05 06:22:04	1.46
+++ mono/metadata/class.c	2001/11/05 11:29:06
@@ -26,7 +26,7 @@
 
 #define CSIZE(x) (sizeof (x) / 4)
 
-gpointer arch_compile_method (MonoMethod *method);
+gpointer arch_create_jit_trampoline (MonoMethod *method, gboolean virtual);
 
 static MonoClass *
 mono_class_create_from_typeref (MonoImage *image, guint32 type_token)
@@ -343,7 +343,7 @@
 				if (im && !(im->flags & METHOD_ATTRIBUTE_ABSTRACT)) {
 					im->slot = io + l;
 					//printf ("  ASLOT%d %s.%s:%s\n", io + l, ic->name_space, ic->name, im->name);
-					vtable [io + l] = arch_compile_method (im);
+					vtable [io + l] = arch_create_jit_trampoline (im, TRUE);
 				}
 			}
 		}
@@ -380,7 +380,7 @@
 			cm->slot = cur_slot++;
 
 		if (!(cm->flags & METHOD_ATTRIBUTE_ABSTRACT))
-			vtable [cm->slot] = arch_compile_method (cm);
+			vtable [cm->slot] = arch_create_jit_trampoline (cm, TRUE);
 	}
 
 	/*
Index: mono/metadata/pedump.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/pedump.c,v
retrieving revision 1.15
diff -u -r1.15 pedump.c
--- mono/metadata/pedump.c	2001/10/15 09:50:03	1.15
+++ mono/metadata/pedump.c	2001/11/05 11:29:06
@@ -19,10 +19,10 @@
 gboolean dump_data = TRUE;
 gboolean dump_tables = FALSE;
 
-gpointer arch_compile_method (MonoMethod *method);
+gpointer arch_create_jit_trampoline (MonoMethod *method, gboolean virtual);
 
 gpointer 
-arch_compile_method (MonoMethod *method)
+arch_create_jit_trampoline (MonoMethod *method, gboolean virtual)
 {
 	return method;
 }