[Mono-list] patch: more jit work + bug fixes
Dietmar Maurer
dietmar@ximian.com
09 Nov 2001 18:38:42 +0100
Index: mono/arch/x86/x86-codegen.h
===================================================================
RCS file: /cvs/public/mono/mono/arch/x86/x86-codegen.h,v
retrieving revision 1.14
diff -u -r1.14 x86-codegen.h
--- mono/arch/x86/x86-codegen.h 2001/11/07 06:33:48 1.14
+++ mono/arch/x86/x86-codegen.h 2001/11/09 13:38:15
@@ -259,6 +259,10 @@
*(inst)++ = 0xcc; \
} while (0)
+#define x86_cld(inst) do { *(inst)++ =(unsigned char)0xfc; } while (0)
+#define x86_stosb(inst) do { *(inst)++ =(unsigned char)0xaa; } while
(0)
+#define x86_stosl(inst) do { *(inst)++ =(unsigned char)0xab; } while
(0)
+
#define x86_prefix(inst,p) do { *(inst)++ =(unsigned char) (p); } while
(0)
#define x86_rdtsc(inst) \
Index: mono/jit/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/jit/ChangeLog,v
retrieving revision 1.38
diff -u -r1.38 ChangeLog
--- mono/jit/ChangeLog 2001/11/09 06:28:40 1.38
+++ mono/jit/ChangeLog 2001/11/09 13:38:15
@@ -1,6 +1,11 @@
2001-11-09 Dietmar Maurer <dietmar@ximian.com>
+ * testjit.c (mono_analyze_stack): new BOX impl.
+
+ * x86.brg: implemented INITOBJ
+
* testjit.c (mono_analyze_stack): finished array support
+ (mono_analyze_stack): reimplemented DUP instruction
2001-11-08 Dietmar Maurer <dietmar@ximian.com>
Index: mono/jit/testjit.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/testjit.c,v
retrieving revision 1.40
diff -u -r1.40 testjit.c
--- mono/jit/testjit.c 2001/11/09 06:28:40 1.40
+++ mono/jit/testjit.c 2001/11/09 13:38:15
@@ -166,6 +166,47 @@
return g_malloc0 (size);
}
+
+typedef void (*MonoCCtor) (void);
+
+/**
+ * mono_jit_init_class:
+ * @klass: the class to initialise
+ *
+ * Initialise the class @klass by calling the class
+ * constructor.
+ */
+static void
+mono_jit_init_class (MonoClass *klass)
+{
+ MonoCCtor cctor;
+ MonoMethod *method;
+ int i;
+
+ if (!klass->metadata_inited)
+ mono_class_metadata_init (klass);
+
+ if (klass->inited)
+ return;
+
+ if (klass->parent && !klass->parent->inited)
+ mono_jit_init_class (klass->parent);
+
+ klass->inited = 1;
+
+ for (i = 0; i < klass->method.count; ++i) {
+ method = klass->methods [i];
+ if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
+ (strcmp (".cctor", method->name) == 0)) {
+
+ cctor = arch_compile_method (method);
+ cctor ();
+ return;
+ }
+ }
+ /* No class constructor found */
+}
+
static int
map_store_svt_type (int svt)
{
@@ -184,6 +225,29 @@
return 0;
}
+static int
+map_stvalue_type (MonoClass *class)
+{
+ int size;
+
+ g_assert (class->valuetype);
+
+ if (!class->inited)
+ mono_jit_init_class (class);
+
+ size = class->instance_size - sizeof (MonoObject);
+
+ switch (size) {
+ case 4:
+ return MB_TERM_STIND_I4;
+ case 2:
+ return MB_TERM_STIND_I2;
+ case 1:
+ return MB_TERM_STIND_I1;
+ }
+ return MB_TERM_STIND_OBJ;
+}
+
/**
* map_stind_type:
* @type: the type to map
@@ -223,19 +287,8 @@
return MB_TERM_STIND_R4;
case MONO_TYPE_R8:
return MB_TERM_STIND_R8;
- case MONO_TYPE_VALUETYPE: {
- int size = type->data.klass->instance_size - sizeof (MonoObject);
-
- switch (size) {
- case 4:
- return MB_TERM_STIND_I4;
- case 2:
- return MB_TERM_STIND_I2;
- case 1:
- return MB_TERM_STIND_I1;
- }
- return MB_TERM_STIND_OBJ;
- }
+ case MONO_TYPE_VALUETYPE:
+ return map_stvalue_type (type->data.klass);
default:
g_warning ("unknown type %02x", type->type);
g_assert_not_reached ();
@@ -576,13 +629,20 @@
return NULL;
}
+/**
+ * Create a duplicate of the value of a tree. This is
+ * easy for trees starting with LDIND/STIND, since the
+ * duplicate is simple a LDIND tree with the same address.
+ * For other trees we have to split the tree into one tree
+ * storing the value to a new temporary variable, and
+ * another tree which loads that value back. We can then
+ * duplicate the second tree.
+ */
static MBTree *
-mono_store_tree (MonoFlowGraph *cfg, int slot, MBTree *s, MBTree **dup)
+ctree_create_dup (MonoMemPool *mp, MBTree *s)
{
- MonoMemPool *mp = cfg->mp;
MBTree *t;
- int vnum;
-
+
switch (s->op) {
case MB_TERM_STIND_I1:
case MB_TERM_LDIND_I1:
@@ -602,6 +662,11 @@
t = mono_ctree_new (mp, MB_TERM_LDIND_I4, t, NULL);
t->svt = VAL_I32;
break;
+ case MB_TERM_LDIND_U4:
+ t = ctree_dup_address (mp, s->left);
+ t = mono_ctree_new (mp, MB_TERM_LDIND_U4, t, NULL);
+ t->svt = VAL_I32;
+ break;
case MB_TERM_STIND_I8:
case MB_TERM_LDIND_I8:
t = ctree_dup_address (mp, s->left);
@@ -620,127 +685,61 @@
t = mono_ctree_new (mp, MB_TERM_LDIND_R8, t, NULL);
t->svt = VAL_DOUBLE;
break;
- default: {
- g_assert (s->svt != VAL_UNKNOWN);
-
- if (slot >= 0)
- vnum = mono_allocate_intvar (cfg, slot, s->svt);
- else {
- int size, align;
- mono_get_val_sizes (s->svt, &size, &align);
- vnum = arch_allocate_var (cfg, size, align, MONO_TEMPVAR, s->svt);
- }
-
- t = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
- t->data.i = vnum;
-
- t = mono_ctree_new (mp, map_store_svt_type (s->svt), t, s);
- t->svt = s->svt;
- }
+ default:
+ g_warning ("unknown op \"%s\"", mono_burg_term_string [s->op]);
+ g_assert_not_reached ();
}
- if (dup)
- *dup = mono_store_tree (cfg, -1, t, NULL);
-
return t;
}
-/**
- * Create a duplicate of the value of a tree. This is
- * easy for trees starting with LDIND/STIND, since the
- * duplicate is simple a LDIND tree with the same address.
- * For other trees we have to split the tree into one tree
- * storing the value to a new temporary variable, and
- * another tree which loads that value back. We can then
- * duplicate the second tree.
- */
static MBTree *
-ctree_create_dup (MonoMemPool *mp, MBTree *s)
+mono_store_tree (MonoFlowGraph *cfg, int slot, MBTree *s, MBTree **dup)
{
+ MonoMemPool *mp = cfg->mp;
MBTree *t;
-
+ int vnum;
+
switch (s->op) {
case MB_TERM_STIND_I1:
case MB_TERM_LDIND_I1:
- t = ctree_dup_address (mp, s->left);
- t->svt = VAL_I32;
- return mono_ctree_new (mp, MB_TERM_LDIND_I1, t, NULL);
case MB_TERM_STIND_I2:
case MB_TERM_LDIND_I2:
- t = ctree_dup_address (mp, s->left);
- t->svt = VAL_I32;
- return mono_ctree_new (mp, MB_TERM_LDIND_I2, t, NULL);
case MB_TERM_STIND_I4:
case MB_TERM_LDIND_I4:
- 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);
- t->svt = VAL_I64;
- return mono_ctree_new (mp, MB_TERM_LDIND_I8, t, NULL);
case MB_TERM_STIND_R4:
case MB_TERM_LDIND_R4:
- t = ctree_dup_address (mp, s->left);
- t->svt = VAL_DOUBLE;
- return mono_ctree_new (mp, MB_TERM_LDIND_R4, t, NULL);
case MB_TERM_STIND_R8:
- case MB_TERM_LDIND_R8:
- t = ctree_dup_address (mp, s->left);
- t->svt = VAL_DOUBLE;
- return mono_ctree_new (mp, MB_TERM_LDIND_R8, t, NULL);
- default:
- g_warning ("unknown op \"%s\"", mono_burg_term_string [s->op]);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return NULL;
-}
-
-typedef void (*MonoCCtor) (void);
-
-/**
- * mono_jit_init_class:
- * @klass: the class to initialise
- *
- * Initialise the class @klass by calling the class
- * constructor.
- */
-static void
-mono_jit_init_class (MonoClass *klass)
-{
- MonoCCtor cctor;
- MonoMethod *method;
- int i;
-
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
-
- if (klass->inited)
- return;
+ case MB_TERM_LDIND_R8: {
+ if (dup)
+ *dup = ctree_create_dup (mp, s);
+ return NULL;
+ }
+ default: {
+ g_assert (s->svt != VAL_UNKNOWN);
- if (klass->parent && !klass->parent->inited)
- mono_jit_init_class (klass->parent);
-
- klass->inited = 1;
+ if (slot >= 0)
+ vnum = mono_allocate_intvar (cfg, slot, s->svt);
+ else {
+ int size, align;
+ mono_get_val_sizes (s->svt, &size, &align);
+ vnum = arch_all_cate_var (cfg, size, align, MONO_TEMPVAR, s->svt);
+ }
- for (i = 0; i < klass->method.count; ++i) {
- method = klass->methods [i];
- if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
- (strcmp (".cctor", method->name) == 0)) {
-
- cctor = arch_compile_method (method);
- cctor ();
- return;
+ t = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
+ t->data.i = vnum;
+
+ t = mono_ctree_new (mp, map_store_svt_type (s->svt), t, s);
+ t->svt = s->svt;
}
}
- /* No class constructor found */
+
+ if (dup)
+ mono_store_tree (cfg, -1, t, dup);
+
+ return t;
}
MonoFlowGraph *
@@ -939,6 +938,7 @@
ip += 5;
break;
case CEE_BR:
+ case CEE_LEAVE:
case CEE_BRTRUE:
case CEE_BRFALSE:
case CEE_BGT:
@@ -971,6 +971,7 @@
ip += 2;
break;
case CEE_BR_S:
+ case CEE_LEAVE_S:
case CEE_BRTRUE_S:
case CEE_BRFALSE_S:
case CEE_BGT_S:
@@ -1014,6 +1015,7 @@
ip++;
break;
case CEE_LDARG:
+ case CEE_INITOBJ:
ip +=5;
break;
default:
@@ -1305,9 +1307,26 @@
c = mono_class_get (image, token);
- t1 = mono_ctree_new (mp, MB_TERM_BOX, *sp, NULL);
+ t1 = mono_ctree_new_leaf (mp, MB_TERM_NEWOBJ);
t1->data.p = c;
- PUSH_TREE (t1, VAL_POINTER);
+ t1->svt = VAL_POINTER;
+
+ t1 = mono_store_tree (cfg, -1, t1, &t2);
+ g_assert (t1);
+
+ ADD_TREE (t1);
+ PUSH_TREE (t2, VAL_POINTER);
+
+ t1 = ctree_create_dup (mp, t2);
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+ t2->data.i = sizeof (MonoObject);
+ t1 = mono_ctree_new (mp, MB_TERM_ADD, t1, t2);
+
+ t1 = mono_ctree_new (mp, map_stvalue_type (c), t1, *sp);
+ ADD_TREE (t1);
+
+ // I need to test this first
+ g_assert_not_reached ();
break;
}
case CEE_UNBOX: {
@@ -1630,6 +1649,7 @@
this->svt = VAL_POINTER;
t1 = mono_store_tree (cfg, -1, this, &this);
+ g_assert (t1);
ADD_TREE (t1);
}
@@ -1671,6 +1691,7 @@
if (newarr) {
t1 = mono_store_tree (cfg, -1, t1, &t2);
+ g_assert (t1);
ADD_TREE (t1);
PUSH_TREE (t2, t2->svt);
@@ -1803,6 +1824,7 @@
if (csig->ret->type != MONO_TYPE_VOID) {
t1 = mono_store_tree (cfg, -1, t1, &t2);
+ g_assert (t1);
ADD_TREE (t1);
PUSH_TREE (t2, t2->svt);
@@ -2169,11 +2191,15 @@
}
case CEE_DUP: {
++ip;
-
+ sp--;
/* fixme: IMO we can use the temp. variable associated
* with the current slot instead of -1
*/
- sp [-1] = mono_store_tree (cfg, -1, sp [-1], &t1);
+ if (t2 = mono_store_tree (cfg, -1, *sp, &t1))
+ ADD_TREE (t2);
+
+ PUSH_TREE (t1, t1->svt);
+ t1 = ctree_create_dup (mp, t1);
PUSH_TREE (t1, t1->svt);
break;
@@ -2233,6 +2259,22 @@
MAKE_BI_ALU (CEQ)
+ case CEE_INITOBJ: {
+ MonoClass *class;
+ guint32 token;
+
+ ++ip;
+ token = read32 (ip);
+ class = mono_class_get (image, token);
+ ip += 4;
+ sp--;
+
+ t1 = mono_ctree_new (mp, MB_TERM_INITOBJ, *sp, NULL);
+ t1->data.i = mono_class_value_size (class, NULL);
+ ADD_TREE (t1);
+
+ break;
+ }
case CEE_LDARG: {
guint32 n;
++ip;
Index: mono/jit/x86.brg
===================================================================
RCS file: /cvs/public/mono/mono/jit/x86.brg,v
retrieving revision 1.33
diff -u -r1.33 x86.brg
--- mono/jit/x86.brg 2001/11/09 06:28:40 1.33
+++ mono/jit/x86.brg 2001/11/09 13:38:15
@@ -118,7 +118,7 @@
%term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT
BGT_UN
%term CEQ
%term CONV_I4 CONV_I1 CONV_I2 CONV_I8 CONV_R8
-%term INTF_ADDR VFUNC_ADDR NOP BOX NEWARR NEWOBJ POP
+%term INTF_ADDR VFUNC_ADDR NOP NEWARR NEWOBJ POP INITOBJ
%term LDLEN
#
@@ -243,6 +243,30 @@
}
}
+stmt: STIND_I1 (addr, reg) {
+ switch (tree->left->data.ainfo.amode) {
+
+ case AMImmediate:
+ x86_mov_mem_reg (s->code, tree->left->data.ainfo.offset,
tree->right->reg1, 1);
+ break;
+
+ case AMBase:
+ x86_mov_membase_reg (s->code, tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset, tree->right->reg1, 1);
+ break;
+ case AMIndex:
+ x86_mov_memindex_reg (s->code, X86_NOBASEREG,
tree->left->data.ainfo.offset,
+ tree->left->data.ainfo.indexreg,
tree->left->data.ainfo.shift,
+ tree->right->reg1, 1);
+ break;
+ case AMBaseIndex:
+ x86_mov_memindex_reg (s->code, tree->left->data.ainfo.basereg,
tree->left->data.ainfo.offset,
+ tree->left->data.ainfo.indexreg,
tree->left->data.ainfo.shift,
+ tree->right->reg1, 1);
+ break;
+ }
+}
+
reg: LDIND_I4 (addr) {
switch (tree->left->data.ainfo.amode) {
@@ -266,6 +290,29 @@
}
}
+reg: LDIND_U1 (addr) {
+ switch (tree->left->data.ainfo.amode) {
+
+ case AMImmediate:
+ x86_mov_reg_mem (s->code, tree->reg1, tree->left->data.ainfo.offset,
1);
+ break;
+
+ case AMBase:
+ x86_mov_reg_membase (s->code, tree->reg1,
tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset, 1);
+ break;
+ case AMIndex:
+ x86_mov_reg_memindex (s->code, tree->reg1, X86_NOBASEREG,
tree->left->data.ainfo.offset,
+ tree->left->data.ainfo.indexreg,
tree->left->data.ainfo.shift, 1);
+ break;
+ case AMBaseIndex:
+ x86_mov_reg_memindex (s->code, tree->reg1,
tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset,
tree->left->data.ainfo.indexreg,
+ tree->left->data.ainfo.shift, 1);
+ break;
+ }
+}
+
reg: LDIND_U4 (addr) {
switch (tree->left->data.ainfo.amode) {
@@ -513,26 +560,6 @@
tree->left->reg1 != X86_ECX);
}
-reg: BOX (reg) {
- if (tree->reg1 != X86_EAX)
- x86_push_reg (s->code, X86_EAX);
- x86_push_reg (s->code, X86_ECX);
- x86_push_reg (s->code, X86_EDX);
-
- x86_push_reg (s->code, tree->left->reg1); //save it to memory
- x86_push_reg (s->code, X86_ESP); // push address to saved value
- x86_push_imm (s->code, tree->data.p);
- x86_call_code (s->code, mono_value_box);
- x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
-
- x86_pop_reg (s->code, X86_EDX);
- x86_pop_reg (s->code, X86_ECX);
- if (tree->reg1 != X86_EAX) {
- x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
- x86_pop_reg (s->code, X86_EAX);
- }
-}
-
# array support
reg: LDLEN (reg) {
x86_mov_reg_membase (s->code, tree->reg1, tree->left->reg1,
@@ -582,6 +609,69 @@
x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
x86_pop_reg (s->code, X86_EAX);
}
+}
+
+stmt: INITOBJ (reg) {
+ int i, j;
+
+ if (i == 1 || i == 2 || i == 4) {
+ int t = X86_ECX;
+
+ if (tree->left->reg1 != X86_EAX)
+ t = X86_EAX;
+
+ x86_push_reg (s->code, t);
+ x86_alu_reg_reg (s->code, X86_XOR, t, t);
+
+ switch (tree->data.i) {
+ case 4:
+ x86_mov_regp_reg (s->code, tree->left->reg1, t, 4);
+ break;
+ case 2:
+ x86_mov_regp_reg (s->code, tree->left->reg1, t, 4);
+ break;
+ case 1:
+ x86_mov_regp_reg (s->code, tree->left->reg1, t, 4);
+ break;
+ }
+ x86_pop_reg (s->code, t);
+
+ return;
+ }
+
+ i = tree->data.i / 4;
+ j = tree->data.i % 4;
+
+ x86_push_reg (s->code, X86_EAX);
+
+ if (tree->left->reg1 != X86_EDI) {
+ x86_push_reg (s->code, X86_EDI);
+ x86_mov_reg_reg (s->code, X86_EDI, tree->left->reg1, 4);
+ }
+
+ if (i) {
+ x86_push_reg (s->code, X86_ECX);
+ x86_alu_reg_reg (s->code, X86_XOR, X86_EAX, X86_EAX);
+ x86_mov_reg_imm (s->code, X86_ECX, i);
+ x86_cld (s->code);
+ x86_prefix (s->code, X86_REP_PREFIX);
+ x86_stosl (s->code);
+ x86_pop_reg (s->code, X86_ECX);
+ }
+
+
+ if (j == 2) {
+ x86_prefix (s->code, X86_OPERAND_PREFIX);
+ x86_stosl (s->code);
+ } else {
+ for (i = 0; i < j; i++)
+ x86_stosb (s->code);
+ }
+
+ if (tree->left->reg1 != X86_EDI)
+ x86_pop_reg (s->code, X86_EDI);
+
+ x86_pop_reg (s->code, X86_EAX);
}
stmt: NOP
Index: mono/metadata/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/metadata/ChangeLog,v
retrieving revision 1.83
diff -u -r1.83 ChangeLog
--- mono/metadata/ChangeLog 2001/11/08 21:38:32 1.83
+++ mono/metadata/ChangeLog 2001/11/09 13:38:15
@@ -1,3 +1,7 @@
+2001-11-09 Dietmar Maurer <dietmar@ximian.com>
+
+ * class.c (mono_class_metadata_init): bug fix: compute the right slot
+
2001-11-07 Miguel de _caza <miguel@ximian.com>
* reflection.c (build_compressed_metadata): Eliminates warnings
Index: mono/metadata/class.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/class.c,v
retrieving revision 1.50
diff -u -r1.50 class.c
--- mono/metadata/class.c 2001/11/08 21:38:32 1.50
+++ mono/metadata/class.c 2001/11/09 13:38:15
@@ -240,9 +240,14 @@
for (k = class->parent; k ; k = k->parent) {
for (i = 0; i < k->interface_count; i++) {
ic = k->interfaces [i];
- if (class->interface_offsets [ic->interface_id] == NULL)
- class->interface_offsets [ic->interface_id] =
- &class->vtable [(k->interface_offsets [ic->interface_id] -
(gpointer)k->vtable)>>2];
+ if (class->interface_offsets [ic->interface_id] == NULL) {
+ int io = (k->interface_offsets [ic->interface_id] -
(gpointer)k->vtable)>>2;
+
+ g_assert (io >= 0);
+ g_assert (io <= class->vtable_size);
+
+ class->interface_offsets [ic->interface_id] = &class->vtable [io];
+ }
}
}
@@ -257,7 +262,10 @@
int j, l, io;
ic = k->interfaces [i];
- io = (class->interface_offsets [ic->interface_id] -
(gpointer)k->vtable)>>2;
+ io = (k->interface_offsets [ic->interface_id] -
(gpointer)k->vtable)>>2;
+
+ g_assert (io >= 0);
+ g_assert (io <= class->vtable_size);
if (k == class) {
for (l = 0; l < ic->method.count; l++) {