X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Finssel.brg;h=a42373faf6fbb36ba75293444fc2c37afeffaf78;hb=94f79d6fcb3a15085bc09f6f12fed9108f3e9a77;hp=c835ff06216c1a9144cad92565b6048583412b75;hpb=27248d2f9f289b8906d329ad60d7c8236da4f90a;p=mono.git diff --git a/mono/mini/inssel.brg b/mono/mini/inssel.brg index c835ff06216..a42373faf6f 100644 --- a/mono/mini/inssel.brg +++ b/mono/mini/inssel.brg @@ -64,7 +64,7 @@ (inst)->opcode = op; \ (inst)->dreg = dr; \ (inst)->sreg1 = sr; \ - (inst)->inst_p1 = (gpointer)imm; \ + (inst)->inst_p1 = (gpointer)(gssize)(imm); \ mono_bblock_add_inst (cfg->cbb, inst); \ } while (0) @@ -74,10 +74,19 @@ inst->opcode = op; \ inst->dreg = dr; \ inst->sreg1 = sr; \ - inst->inst_p1 = (gpointer)imm; \ + inst->inst_p1 = (gpointer)(gssize)(imm); \ mono_bblock_add_inst (cfg->cbb, inst); \ } while (0) +#define MONO_EMIT_BIALU_MEMBASE(cfg,tree,op,dr,sr,basereg,offset) do { \ + tree->opcode = op; \ + tree->dreg = dr; \ + tree->sreg1 = sr; \ + tree->sreg2 = basereg; \ + tree->inst_offset = offset; \ + mono_bblock_add_inst (s->cbb, tree); \ + } while (0) + #define MONO_EMIT_LOAD_MEMBASE(cfg,inst,dr,base,offset) do { \ (inst)->opcode = OP_LOAD_MEMBASE; \ (inst)->dreg = dr; \ @@ -234,6 +243,7 @@ #endif #define MONO_EMIT_NEW_CLASSCONST(cfg,dr,imm) MONO_EMIT_NEW_AOTCONST(cfg,dr,imm,MONO_PATCH_INFO_CLASS) +#define MONO_EMIT_NEW_VTABLECONST(cfg,dest,vtable) MONO_EMIT_NEW_AOTCONST ((cfg), (dest), (cfg)->compile_aot ? (gpointer)((vtable)->klass) : (vtable), MONO_PATCH_INFO_VTABLE) #define MONO_EMIT_NEW_BRANCH_BLOCK(cfg,op,targetbb) do { \ MonoInst *inst; \ @@ -389,6 +399,19 @@ stmt: OP_DUMMY_USE (CEE_LDIND_I (OP_REGVAR)) { stmt: OP_DUMMY_USE (CEE_LDIND_I (OP_REGOFFSET)) { } +stmt: OP_DUMMY_USE (CEE_LDIND_REF (OP_REGOFFSET)) { +} + +stmt: OP_DUMMY_STORE { +} + +stmt: OP_NOT_REACHED { +} + +stmt: OP_MEMORY_BARRIER { + mono_bblock_add_inst (s->cbb, tree); +} + # # load/store operations # @@ -625,14 +648,17 @@ reg: CEE_CONV_U2 (reg) { reg: CEE_CONV_U4 (reg), reg: CEE_CONV_U (reg), -reg: CEE_CONV_I (reg), -reg: CEE_CONV_OVF_I4 (reg) { +reg: CEE_CONV_I (reg) { if (sizeof (void *) == 8) MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1); else MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } +reg: CEE_CONV_OVF_I4 (reg) { + MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); +} + reg: CEE_CONV_OVF_U4 (reg), reg: CEE_CONV_OVF_I4_UN (reg) { if (sizeof (void *) == 8) { @@ -724,7 +750,7 @@ reg: OP_TLS_GET { mono_bblock_add_inst (s->cbb, tree); } -stmt: CEE_SWITCH (reg) { +stmt: CEE_SWITCH (reg) "2" { MonoInst *label; int offset_reg = mono_regstate_next_int (s->rs); int target_reg = mono_regstate_next_int (s->rs); @@ -739,7 +765,7 @@ stmt: CEE_SWITCH (reg) { else MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, offset_reg, state->left->reg1, 2); mono_bblock_add_inst (s->cbb, label); - if (mono_compile_aot) { + if (s->compile_aot) { int table_reg = mono_regstate_next_int (s->rs); int sum_reg = mono_regstate_next_int (s->rs); MonoJumpInfoBBTable *table; @@ -904,15 +930,20 @@ stmt: OP_RETHROW (reg) { MONO_EMIT_UNALU (s, tree, OP_RETHROW, -1, state->left->reg1); } -stmt: OP_THROW_OR_NULL (reg) { - MonoInst *object_is_null; +stmt: OP_THROW_OR_NULL (reg, reg) { + MonoInst *dont_throw; - MONO_NEW_LABEL (s, object_is_null); + MONO_NEW_LABEL (s, dont_throw); - MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, 0, state->left->reg1, 0); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BEQ, object_is_null); + /* + * Currently, we allways rethrow the abort exception, despite the fact + * that this is not correct. See thread6.cs for an example. But propagating + * the abort exception is more important than getting the sematics right. + */ + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0); + MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BEQ, dont_throw); MONO_EMIT_UNALU (s, tree, CEE_THROW, -1, state->left->reg1); - mono_bblock_add_inst (s->cbb, object_is_null); + mono_bblock_add_inst (s->cbb, dont_throw); } stmt: CEE_THROW (CEE_LDIND_REF (OP_REGVAR)) { @@ -964,21 +995,21 @@ reg: CEE_ISINST (reg) { int klass_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE (s, vtable_reg, obj_reg, G_STRUCT_OFFSET (MonoObject, vtable)); - MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); if (klass->rank) { int rank_reg = mono_regstate_next_int (s->rs); int eclass_reg = mono_regstate_next_int (s->rs); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, rank_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, rank)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, rank)); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, rank_reg, klass->rank); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, false_label); + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); MONO_EMIT_NEW_LOAD_MEMBASE (s, eclass_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, cast_class)); if (klass->cast_class == mono_defaults.object_class) { int parent_reg = mono_regstate_next_int (s->rs); - int const_reg; + int const_reg = -1; MONO_EMIT_NEW_LOAD_MEMBASE (s, parent_reg, eclass_reg, G_STRUCT_OFFSET (MonoClass, parent)); - if (mono_compile_aot) { + if (s->compile_aot) { const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class->parent); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, parent_reg, const_reg); @@ -986,7 +1017,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, parent_reg, mono_defaults.enum_class->parent); } MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, object_is_null); - if (mono_compile_aot) { + if (s->compile_aot) { MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); } else { @@ -995,9 +1026,9 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BEQ, object_is_null); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, false_label); } else if (klass->cast_class == mono_defaults.enum_class->parent) { - int const_reg; + int const_reg = -1; - if (mono_compile_aot) { + if (s->compile_aot) { const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class->parent); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); @@ -1005,7 +1036,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, eclass_reg, mono_defaults.enum_class->parent); } MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BEQ, object_is_null); - if (mono_compile_aot) { + if (s->compile_aot) { MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); } else { @@ -1014,7 +1045,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BEQ, object_is_null); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, false_label); } else if (klass->cast_class == mono_defaults.enum_class) { - if (mono_compile_aot) { + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); @@ -1037,9 +1068,27 @@ reg: CEE_ISINST (reg) { /* the object_is_null target simply copies the input register to the output */ mini_emit_isninst_cast (s, eclass_reg, klass->cast_class, false_label, object_is_null); } - } else { + } else if (mono_class_is_nullable (klass)) { + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); /* the object_is_null target simply copies the input register to the output */ - mini_emit_isninst_cast (s, klass_reg, klass, false_label, object_is_null); + mini_emit_isninst_cast (s, klass_reg, klass->cast_class, false_label, object_is_null); + } else { + if (!s->compile_aot && !(s->opt & MONO_OPT_SHARED) && (klass->flags & TYPE_ATTRIBUTE_SEALED)) { + /* the remoting code is broken, access the class for now */ + if (0) { + MonoVTable *vt = mono_class_vtable (s->domain, klass); + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, vtable_reg, vt); + } else { + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, klass_reg, klass); + } + MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, false_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, object_is_null); + } else { + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); + /* the object_is_null target simply copies the input register to the output */ + mini_emit_isninst_cast (s, klass_reg, klass, false_label, object_is_null); + } } } @@ -1057,7 +1106,7 @@ reg: OP_CISINST (reg) { 1) if the object is not instance of the class, 2) if the object is a proxy whose type cannot be determined */ - MonoClass *klass = tree->inst_newa_class; + MonoClass *klass = tree->inst_newa_class; MonoInst *end_label, *true_label, *false_label, *false2_label; MonoInst *no_proxy_label, *interface_fail_label; int obj_reg = state->left->reg1; @@ -1080,7 +1129,7 @@ reg: OP_CISINST (reg) { mono_bblock_add_inst (s->cbb, interface_fail_label); MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, tmp_reg, G_STRUCT_OFFSET (MonoVTable, klass)); - if (mono_compile_aot) { + if (s->compile_aot) { int tproxy_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, tproxy_reg, mono_defaults.transparent_proxy_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, klass_reg, tproxy_reg); @@ -1099,7 +1148,7 @@ reg: OP_CISINST (reg) { MONO_NEW_LABEL (s, no_proxy_label); - if (mono_compile_aot) { + if (s->compile_aot) { int tproxy_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, tproxy_reg, mono_defaults.transparent_proxy_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, klass_reg, tproxy_reg); @@ -1141,9 +1190,7 @@ reg: OP_UNBOXCAST (reg) { int rank_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE (s, vtable_reg, obj_reg, G_STRUCT_OFFSET (MonoObject, vtable)); - MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, rank_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, rank)); - MONO_EMIT_NEW_LOAD_MEMBASE (s, eclass_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, element_class)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, rank)); /* FIXME: generics */ g_assert (klass->rank == 0); @@ -1152,12 +1199,14 @@ reg: OP_UNBOXCAST (reg) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, rank_reg, 0); MONO_EMIT_NEW_COND_EXC (s, NE_UN, "InvalidCastException"); - if (mono_compile_aot) { + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); + MONO_EMIT_NEW_LOAD_MEMBASE (s, eclass_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, element_class)); + + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, klass->element_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); - } - else { + } else { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, eclass_reg, klass->element_class); } @@ -1183,21 +1232,21 @@ reg: CEE_CASTCLASS (reg) { int klass_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE (s, vtable_reg, obj_reg, G_STRUCT_OFFSET (MonoObject, vtable)); - MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); if (klass->rank) { int rank_reg = mono_regstate_next_int (s->rs); int eclass_reg = mono_regstate_next_int (s->rs); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, rank_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, rank)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, rank)); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, rank_reg, klass->rank); MONO_EMIT_NEW_COND_EXC (s, NE_UN, "InvalidCastException"); + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); MONO_EMIT_NEW_LOAD_MEMBASE (s, eclass_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, cast_class)); if (klass->cast_class == mono_defaults.object_class) { int parent_reg = mono_regstate_next_int (s->rs); - int const_reg; + int const_reg = -1; MONO_EMIT_NEW_LOAD_MEMBASE (s, parent_reg, eclass_reg, G_STRUCT_OFFSET (MonoClass, parent)); - if (mono_compile_aot) { + if (s->compile_aot) { const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class->parent); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, parent_reg, const_reg); @@ -1205,7 +1254,7 @@ reg: CEE_CASTCLASS (reg) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, parent_reg, mono_defaults.enum_class->parent); } MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, object_is_null); - if (mono_compile_aot) { + if (s->compile_aot) { MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); } else { @@ -1214,14 +1263,14 @@ reg: CEE_CASTCLASS (reg) { MONO_EMIT_NEW_COND_EXC (s, NE_UN, "InvalidCastException"); } else if (klass->cast_class == mono_defaults.enum_class->parent) { int const_reg = mono_regstate_next_int (s->rs); - if (mono_compile_aot) { + if (s->compile_aot) { MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class->parent); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); } else { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, eclass_reg, mono_defaults.enum_class->parent); } MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BEQ, object_is_null); - if (mono_compile_aot) { + if (s->compile_aot) { MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); } else { @@ -1229,7 +1278,7 @@ reg: CEE_CASTCLASS (reg) { } MONO_EMIT_NEW_COND_EXC (s, NE_UN, "InvalidCastException"); } else if (klass->cast_class == mono_defaults.enum_class) { - if (mono_compile_aot) { + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, mono_defaults.enum_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, eclass_reg, const_reg); @@ -1251,7 +1300,20 @@ reg: CEE_CASTCLASS (reg) { MONO_EMIT_NEW_COND_EXC (s, NE_UN, "InvalidCastException"); } } else { - mini_emit_castclass (s, klass_reg, klass); + if (!s->compile_aot && !(s->opt & MONO_OPT_SHARED) && (klass->flags & TYPE_ATTRIBUTE_SEALED)) { + /* the remoting code is broken, access the class for now */ + if (0) { + MonoVTable *vt = mono_class_vtable (s->domain, klass); + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, vtable_reg, vt); + } else { + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, klass_reg, klass); + } + MONO_EMIT_NEW_COND_EXC (s, NE_UN, "InvalidCastException"); + } else { + MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); + mini_emit_castclass (s, klass_reg, klass); + } } } @@ -1287,7 +1349,7 @@ reg: OP_CCASTCLASS (reg) { mono_bblock_add_inst (s->cbb, fail_label); MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, tmp_reg, G_STRUCT_OFFSET (MonoVTable, klass)); - if (mono_compile_aot) { + if (s->compile_aot) { int tproxy_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, tproxy_reg, mono_defaults.transparent_proxy_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, klass_reg, tproxy_reg); @@ -1315,7 +1377,7 @@ reg: OP_CCASTCLASS (reg) { MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp_reg, obj_reg, G_STRUCT_OFFSET (MonoObject, vtable)); MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, tmp_reg, G_STRUCT_OFFSET (MonoVTable, klass)); - if (mono_compile_aot) { + if (s->compile_aot) { int tproxy_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, tproxy_reg, mono_defaults.transparent_proxy_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, klass_reg, tproxy_reg); @@ -1364,7 +1426,7 @@ lreg: OP_LSHR_UN (lreg, reg) { # # string support # -reg: OP_GETCHR (reg, reg) { +reg: OP_GETCHR (reg, reg) "4" { int mult_reg = mono_regstate_next_int (s->rs); int add_reg = mono_regstate_next_int (s->rs); @@ -1382,6 +1444,19 @@ reg: OP_GETCHR (reg, OP_ICONST) { MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADU2_MEMBASE, state->reg1, state->left->reg1, ind); } +reg: OP_STR_CHAR_ADDR (reg, reg) "4" { + int mult_reg = mono_regstate_next_int (s->rs); + int add_reg = mono_regstate_next_int (s->rs); + + /* + * The corlib functions check for oob already. + * MONO_EMIT_BOUNDS_CHECK (s, state->left->reg1, MonoString, length, state->right->reg1); + */ + MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, mult_reg, state->right->reg1, 1); + MONO_EMIT_NEW_BIALU (s, CEE_ADD, add_reg, mult_reg, state->left->reg1); + MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, add_reg, G_STRUCT_OFFSET (MonoString, chars)); +} + reg: OP_STRLEN (reg) { MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->reg1, state->left->reg1, G_STRUCT_OFFSET (MonoString, length)); @@ -1396,12 +1471,7 @@ reg: OP_GETTYPE (reg) { reg: OP_GETHASHCODE (reg) { int t1 = mono_regstate_next_int (s->rs); - #if HAVE_BOEHM_GC #define MONO_OBJECT_ALIGNMENT_SHIFT 3 - #else - #define MONO_OBJECT_ALIGNMENT_SHIFT 2 - #endif - /* return (GPOINTER_TO_UINT (this) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u; */ @@ -1419,32 +1489,40 @@ reg: CEE_LDLEN (reg) { reg: OP_ARRAY_RANK (reg) { int vtable_reg = mono_regstate_next_int (s->rs); - int class_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, vtable_reg, state->left->reg1, G_STRUCT_OFFSET (MonoObject, vtable)); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, class_reg, - vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, - class_reg, G_STRUCT_OFFSET (MonoClass, rank)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU1_MEMBASE, state->reg1, + vtable_reg, G_STRUCT_OFFSET (MonoVTable, rank)); } reg: OP_CHECK_ARRAY_TYPE (reg) { + + MonoClass* array_class = mono_array_class_get (tree->klass, 1); + int vtable_reg = mono_regstate_next_int (s->rs); - int class_reg = mono_regstate_next_int (s->rs); - int elclass_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, vtable_reg, state->left->reg1, G_STRUCT_OFFSET (MonoObject, vtable)); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, class_reg, - vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, elclass_reg, - class_reg, G_STRUCT_OFFSET (MonoClass, element_class)); - if (mono_compile_aot) { - int klass_reg = mono_regstate_next_int (s->rs); - MONO_EMIT_NEW_CLASSCONST (s, klass_reg, tree->klass); - MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, elclass_reg, klass_reg); + + if (s->opt & MONO_OPT_SHARED) { + int class_reg = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, class_reg, + vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); + if (s->compile_aot) { + int klass_reg = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_CLASSCONST (s, klass_reg, array_class); + MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, class_reg, klass_reg); + } else { + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, class_reg, array_class); + } } else { - MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, elclass_reg, tree->klass); + if (s->compile_aot) { + int vt_reg = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_VTABLECONST (s, vt_reg, mono_class_vtable (s->domain, array_class)); + MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, vtable_reg, vt_reg); + } else { + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, vtable_reg, mono_class_vtable (s->domain, array_class)); + } } MONO_EMIT_NEW_COND_EXC (s, NE_UN, "ArrayTypeMismatchException"); @@ -1474,7 +1552,7 @@ reg: CEE_LDELEMA (reg, reg) "20" { reg: CEE_REFANYVAL (reg) { int klass_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, state->left->reg1, G_STRUCT_OFFSET (MonoTypedRef, klass)); - if (mono_compile_aot) { + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, tree->inst_newa_class); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, klass_reg, const_reg); @@ -1492,7 +1570,7 @@ reg: OP_REFANYTYPE (reg) { stmt: CEE_MKREFANY (OP_GROUP (reg, OP_ICONST), reg), stmt: CEE_MKREFANY (OP_GROUP (reg, OP_I8CONST), reg) { MonoClass *klass = (MonoClass*)(tree->inst_left->inst_right->inst_p0); - if (mono_compile_aot) { + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); int type_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, klass); @@ -1517,13 +1595,13 @@ static void mini_emit_max_iid_check (MonoCompile *s, int max_iid_reg, MonoClass *klass, MonoInst *false_target) { - if (mono_compile_aot) { + if (s->compile_aot) { int iid_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_AOTCONST (s, iid_reg, klass, MONO_PATCH_INFO_IID); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, max_iid_reg, iid_reg); - } - else + } else { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, max_iid_reg, klass->interface_id); + } if (false_target) MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT_UN, false_target); else @@ -1537,7 +1615,7 @@ mini_emit_max_iid_check_vtable (MonoCompile *s, int vtable_reg, MonoClass *klass { int max_iid_reg = mono_regstate_next_int (s->rs); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, max_iid_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, max_interface_id)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU2_MEMBASE, max_iid_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, max_interface_id)); mini_emit_max_iid_check (s, max_iid_reg, klass, false_target); } @@ -1548,37 +1626,25 @@ mini_emit_max_iid_check_class (MonoCompile *s, int klass_reg, MonoClass *klass, { int max_iid_reg = mono_regstate_next_int (s->rs); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, max_iid_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, max_interface_id)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU2_MEMBASE, max_iid_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, max_interface_id)); mini_emit_max_iid_check (s, max_iid_reg, klass, false_target); } +/* Emit code which loads interface_offsets [klass->interface_id] + * The array is stored in memory before vtable. + */ static void -mini_emit_load_intf_reg (MonoCompile *s, int intf_reg, int ioffset_reg, MonoClass *klass) +mini_emit_load_intf_reg_vtable (MonoCompile *s, int intf_reg, int vtable_reg, MonoClass *klass) { - if (mono_compile_aot) { + if (s->compile_aot) { + int ioffset_reg = mono_regstate_next_int (s->rs); int iid_reg = mono_regstate_next_int (s->rs); - MONO_EMIT_NEW_AOTCONST (s, iid_reg, klass, MONO_PATCH_INFO_IID); - /* FIXME: Do a shift instead */ -#if SIZEOF_VOID_P == 8 - MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, iid_reg, iid_reg, 3); -#else - MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, iid_reg, iid_reg, 2); -#endif - MONO_EMIT_NEW_BIALU (s, CEE_ADD, ioffset_reg, ioffset_reg, iid_reg); + MONO_EMIT_NEW_AOTCONST (s, iid_reg, klass, MONO_PATCH_INFO_ADJUSTED_IID); + MONO_EMIT_NEW_BIALU (s, OP_PADD, ioffset_reg, iid_reg, vtable_reg); MONO_EMIT_NEW_LOAD_MEMBASE (s, intf_reg, ioffset_reg, 0); + } else { + MONO_EMIT_NEW_LOAD_MEMBASE (s, intf_reg, vtable_reg, -((klass->interface_id + 1) * SIZEOF_VOID_P)); } - else - MONO_EMIT_NEW_LOAD_MEMBASE (s, intf_reg, ioffset_reg, klass->interface_id * SIZEOF_VOID_P); -} - -/* Emit code which loads ->interface_offsets [klass->interface_id] */ -static void -mini_emit_load_intf_reg_vtable (MonoCompile *s, int intf_reg, int vtable_reg, MonoClass *klass) -{ - int ioffset_reg = mono_regstate_next_int (s->rs); - - MONO_EMIT_NEW_LOAD_MEMBASE (s, ioffset_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, interface_offsets)); - mini_emit_load_intf_reg (s, intf_reg, ioffset_reg, klass); } /* Emit code which loads ->interface_offsets [klass->interface_id] */ @@ -1588,7 +1654,17 @@ mini_emit_load_intf_reg_class (MonoCompile *s, int intf_reg, int klass_reg, Mono int ioffset_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE (s, ioffset_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, interface_offsets)); - mini_emit_load_intf_reg (s, intf_reg, ioffset_reg, klass); + + if (s->compile_aot) { + int iid_reg = mono_regstate_next_int (s->rs); + int shifted_iid_reg = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_AOTCONST (s, iid_reg, klass, MONO_PATCH_INFO_IID); + MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, shifted_iid_reg, iid_reg, 2); + MONO_EMIT_NEW_BIALU (s, CEE_ADD, ioffset_reg, ioffset_reg, shifted_iid_reg); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, intf_reg, ioffset_reg, 0); + } else { + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, intf_reg, ioffset_reg, klass->interface_id * sizeof (int)); + } } void @@ -1602,7 +1678,7 @@ mini_emit_virtual_call (MonoCompile *cfg, void *st, MonoInst *tree, int novirtop mono_arch_emit_this_vret_args (cfg, (MonoCallInst*)tree, this_reg, state->left->tree->type, novirtop == OP_VCALL? state->right->reg1: -1); if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) || - ((method->flags & METHOD_ATTRIBUTE_FINAL) && + ((method->flags & METHOD_ATTRIBUTE_FINAL) && method->wrapper_type != MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK)) { /* * the method is not virtual, we just need to ensure this is not null @@ -1621,6 +1697,9 @@ mini_emit_virtual_call (MonoCompile *cfg, void *st, MonoInst *tree, int novirtop return; } + /* Initialize method->slot */ + mono_class_setup_vtable (method->klass); + vtable_reg = mono_regstate_next_int (cfg->rs); MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, this_reg, G_STRUCT_OFFSET (MonoObject, vtable)); if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { @@ -1647,13 +1726,13 @@ mini_emit_isninst_cast (MonoCompile *s, int klass_reg, MonoClass *klass, MonoIns int stype = mono_regstate_next_int (s->rs); if (klass->idepth > MONO_DEFAULT_SUPERTABLE_SIZE) { - MONO_EMIT_NEW_LOAD_MEMBASE (s, idepth_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, idepth)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU2_MEMBASE, idepth_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, idepth)); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, idepth_reg, klass->idepth); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT_UN, false_target); } MONO_EMIT_NEW_LOAD_MEMBASE (s, stypes_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, supertypes)); MONO_EMIT_NEW_LOAD_MEMBASE (s, stype, stypes_reg, ((klass->idepth - 1) * SIZEOF_VOID_P)); - if (mono_compile_aot) { + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, klass); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, stype, const_reg); @@ -1699,13 +1778,13 @@ mini_emit_castclass (MonoCompile *s, int klass_reg, MonoClass *klass) int stype = mono_regstate_next_int (s->rs); if (klass->idepth > MONO_DEFAULT_SUPERTABLE_SIZE) { - MONO_EMIT_NEW_LOAD_MEMBASE (s, idepth_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, idepth)); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU2_MEMBASE, idepth_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, idepth)); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, idepth_reg, klass->idepth); MONO_EMIT_NEW_COND_EXC (s, LT_UN, "InvalidCastException"); } MONO_EMIT_NEW_LOAD_MEMBASE (s, stypes_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, supertypes)); MONO_EMIT_NEW_LOAD_MEMBASE (s, stype, stypes_reg, ((klass->idepth - 1) * SIZEOF_VOID_P)); - if (mono_compile_aot) { + if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_CLASSCONST (s, const_reg, klass); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, stype, const_reg); @@ -1787,7 +1866,7 @@ mini_emit_memcpy (MonoCompile *s, int destreg, int doffset, int srcreg, int soff } void -mini_emit_memset (MonoCompile *s, int destreg, int offset, int size, int val, int alignl) +mini_emit_memset (MonoCompile *s, int destreg, int offset, int size, int val, int align) { int val_reg = mono_regstate_next_int (s->rs); @@ -1796,13 +1875,21 @@ mini_emit_memset (MonoCompile *s, int destreg, int offset, int size, int val, in else MONO_EMIT_NEW_ICONST (s, val_reg, val); + /* FIXME: consider alignment for archs that need it. */ +#if !NO_UNALIGNED_ACCESS if (sizeof (gpointer) == 8) { + if (offset % 8) { + MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg); + offset += 4; + size -= 4; + } while (size >= 8) { MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg); offset += 8; size -= 8; } } +#endif while (size >= 4) { MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg); @@ -1841,8 +1928,7 @@ mini_emit_aotconst (MonoCompile *cfg, int dreg, MonoJumpInfoType patch_type, gpo if (cfg->got_var->opcode == OP_REGOFFSET) { got_var_reg = mono_regstate_next_int (cfg->rs); MONO_EMIT_NEW_LOAD_MEMBASE (cfg, got_var_reg, cfg->got_var->inst_basereg, cfg->got_var->inst_offset); - } - else { + } else { g_assert (cfg->got_var->opcode == OP_REGVAR); got_var_reg = cfg->got_var->dreg; } @@ -1877,6 +1963,8 @@ ldind_to_load_membase (int opcode) return OP_LOAD_MEMBASE; case CEE_LDIND_REF: return OP_LOAD_MEMBASE; + case CEE_LDIND_I8: + return OP_LOADI8_MEMBASE; default: g_assert_not_reached (); }