X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmethod-to-ir.c;h=7d8dce75ca07b42fd218a2507ec0102d551a8f7e;hb=012f8610237dfe44034c9d8daea0b90fac75ca9f;hp=084730f031124c774d734470f315feee42a339f5;hpb=b89b696e71fbcf94520cf70aeb636658951a50a6;p=mono.git diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 084730f0311..7d8dce75ca0 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -1070,6 +1070,7 @@ type_from_op (MonoCompile *cfg, MonoInst *ins, MonoInst *src1, MonoInst *src2) break; case STACK_PTR: case STACK_MP: + case STACK_OBJ: #if SIZEOF_VOID_P == 8 ins->opcode = OP_LCONV_TO_U; #else @@ -3972,6 +3973,8 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono /* Set target field */ /* Optimize away setting of NULL target */ if (!MONO_INS_IS_PCONST_NULL (target)) { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, target->dreg, 0); + MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException"); MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, MONO_STRUCT_OFFSET (MonoDelegate, target), target->dreg); if (cfg->gen_write_barriers) { dreg = alloc_preg (cfg); @@ -6132,9 +6135,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, prev_args = cfg->args; prev_arg_types = cfg->arg_types; prev_inlined_method = cfg->inlined_method; - cfg->inlined_method = cmethod; - cfg->ret_var_set = FALSE; - cfg->inline_depth ++; + prev_ret_var_set = cfg->ret_var_set; prev_real_offset = cfg->real_offset; prev_cbb_hash = cfg->cbb_hash; prev_cil_offset_to_bb = cfg->cil_offset_to_bb; @@ -6144,9 +6145,12 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, prev_cbb = cfg->cbb; prev_current_method = cfg->current_method; prev_generic_context = cfg->generic_context; - prev_ret_var_set = cfg->ret_var_set; prev_disable_inline = cfg->disable_inline; + cfg->inlined_method = cmethod; + cfg->ret_var_set = FALSE; + cfg->inline_depth ++; + if (ip && *ip == CEE_CALLVIRT && !(cmethod->flags & METHOD_ATTRIBUTE_STATIC)) virtual_ = TRUE; @@ -7215,7 +7219,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b { MonoError error; MonoInst *ins, **sp, **stack_start; - MonoBasicBlock *tblock = NULL, *init_localsbb = NULL; + MonoBasicBlock *tblock = NULL; + MonoBasicBlock *init_localsbb = NULL, *init_localsbb2 = NULL; MonoSimpleBasicBlock *bb = NULL, *original_bb = NULL; MonoMethod *cmethod, *method_definition; MonoInst **arg_array; @@ -7282,7 +7287,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b seq_points = FALSE; } - if (cfg->gen_sdb_seq_points && cfg->method == method) { + if (cfg->method == method) + cfg->coverage_info = mono_profiler_coverage_alloc (cfg->method, header->code_size); + + if ((cfg->gen_sdb_seq_points && cfg->method == method) || cfg->coverage_info) { minfo = mono_debug_lookup_method (method); if (minfo) { MonoSymSeqPoint *sps; @@ -7377,9 +7385,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cfg->dont_inline = g_list_prepend (cfg->dont_inline, method); if (cfg->method == method) { - - cfg->coverage_info = mono_profiler_coverage_alloc (cfg->method, header->code_size); - /* ENTRY BLOCK */ NEW_BBLOCK (cfg, start_bblock); cfg->bb_entry = start_bblock; @@ -7552,7 +7557,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b init_localsbb->next_bb = cfg->cbb; link_bblock (cfg, start_bblock, init_localsbb); link_bblock (cfg, init_localsbb, cfg->cbb); - + init_localsbb2 = init_localsbb; cfg->cbb = init_localsbb; if (cfg->gsharedvt && cfg->method == method) { @@ -7770,33 +7775,33 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (sym_seq_points) mono_bitset_set_fast (seq_point_set_locs, ip - header->code); - } - - cfg->cbb->real_offset = cfg->real_offset; - if ((cfg->method == method) && cfg->coverage_info) { - guint32 cil_offset = ip - header->code; - gpointer counter = &cfg->coverage_info->data [cil_offset].count; - cfg->coverage_info->data [cil_offset].cil_code = ip; + if ((cfg->method == method) && cfg->coverage_info) { + guint32 cil_offset = ip - header->code; + gpointer counter = &cfg->coverage_info->data [cil_offset].count; + cfg->coverage_info->data [cil_offset].cil_code = ip; - if (mono_arch_opcode_supported (OP_ATOMIC_ADD_I4)) { - MonoInst *one_ins, *load_ins; + if (mono_arch_opcode_supported (OP_ATOMIC_ADD_I4)) { + MonoInst *one_ins, *load_ins; - EMIT_NEW_PCONST (cfg, load_ins, counter); - EMIT_NEW_ICONST (cfg, one_ins, 1); - MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_I4); - ins->dreg = mono_alloc_ireg (cfg); - ins->inst_basereg = load_ins->dreg; - ins->inst_offset = 0; - ins->sreg2 = one_ins->dreg; - ins->type = STACK_I4; - MONO_ADD_INS (cfg->cbb, ins); - } else { - EMIT_NEW_PCONST (cfg, ins, counter); - MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, ins->dreg, 0, 1); + EMIT_NEW_PCONST (cfg, load_ins, counter); + EMIT_NEW_ICONST (cfg, one_ins, 1); + MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_I4); + ins->dreg = mono_alloc_ireg (cfg); + ins->inst_basereg = load_ins->dreg; + ins->inst_offset = 0; + ins->sreg2 = one_ins->dreg; + ins->type = STACK_I4; + MONO_ADD_INS (cfg->cbb, ins); + } else { + EMIT_NEW_PCONST (cfg, ins, counter); + MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, ins->dreg, 0, 1); + } } } + cfg->cbb->real_offset = cfg->real_offset; + if (cfg->verbose_level > 3) printf ("converting (in B%d: stack: %d) %s", cfg->cbb->block_num, (int)(sp - stack_start), mono_disasm_code_one (NULL, method, ip, NULL)); @@ -8843,6 +8848,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } for (i = 0; i < n; ++i) EMIT_NEW_ARGSTORE (cfg, ins, i, sp [i]); + + mini_profiler_emit_tail_call (cfg, cmethod); + MONO_INST_NEW (cfg, ins, OP_BR); MONO_ADD_INS (cfg->cbb, ins); tblock = start_bblock->out_bb [0]; @@ -11777,6 +11785,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (sp != stack_start) UNVERIFIED; + mini_profiler_emit_leave (cfg, sp [0]); + MONO_INST_NEW (cfg, ins, OP_BR); ins->inst_target_bb = end_bblock; MONO_ADD_INS (cfg->cbb, ins); @@ -11831,7 +11841,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cfg->dyn_call_var->flags |= MONO_INST_VOLATILE; } - /* Has to use a call inst since it local regalloc expects it */ + /* Has to use a call inst since local regalloc expects it */ MONO_INST_NEW_CALL (cfg, call, OP_DYN_CALL); ins = (MonoInst*)call; sp -= 2; @@ -11840,6 +11850,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MONO_ADD_INS (cfg->cbb, ins); cfg->param_area = MAX (cfg->param_area, cfg->backend->dyn_call_param_area); + /* OP_DYN_CALL might need to allocate a dynamically sized param area */ + cfg->flags |= MONO_CFG_HAS_ALLOCA; ip += 2; inline_costs += 10 * num_calls++; @@ -11923,6 +11935,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (next_bb) MONO_START_BB (cfg, next_bb); + /* + * Parts of the initlocals code needs to come after this, since it might call methods like memset. + */ + init_localsbb2 = cfg->cbb; + NEW_BBLOCK (cfg, next_bb); + MONO_START_BB (cfg, next_bb); + ip += 2; break; } @@ -12697,6 +12716,14 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cfg->cbb = init_localsbb; cfg->ip = NULL; for (i = 0; i < header->num_locals; ++i) { + /* + * Vtype initialization might need to be done after CEE_JIT_ATTACH, since it can make calls to memset (), + * which need the trampoline code to work. + */ + if (MONO_TYPE_ISSTRUCT (header->locals [i])) + cfg->cbb = init_localsbb2; + else + cfg->cbb = init_localsbb; emit_init_local (cfg, i, header->locals [i], init_locals); } }