X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=046572a332925011fdfb5b9d33a0f3ec30c14f7a;hb=3e69ff3ae72acec33c471236da49ed6c78b26dc4;hp=0dfd1ce1487ddc05e00f6211a8484bda71471c3f;hpb=ac32aa114ab7cca67498ae8da30188bbbd8923f0;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 0dfd1ce1487..046572a3329 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -855,7 +855,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, inst->backend.is_pinvoke = 0; inst->dreg = vreg; - if (inst->klass->exception_type) + if (mono_class_has_failure (inst->klass)) mono_cfg_set_exception (cfg, MONO_EXCEPTION_TYPE_LOAD); if (cfg->compute_gc_maps) { @@ -1261,7 +1261,7 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile) if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS) mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "%s", msg); - else if (info->exception_type == info->exception_type == MONO_EXCEPTION_FIELD_ACCESS) + else if (info->exception_type == MONO_EXCEPTION_FIELD_ACCESS) mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "%s", msg); else if (info->exception_type == MONO_EXCEPTION_UNVERIFIABLE_IL) mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", msg); @@ -1715,7 +1715,7 @@ mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_s size = mini_type_stack_size (t, &ialign); align = ialign; - if (mono_class_from_mono_type (t)->exception_type) + if (mono_class_has_failure (mono_class_from_mono_type (t))) mono_cfg_set_exception (cfg, MONO_EXCEPTION_TYPE_LOAD); if (MONO_CLASS_IS_SIMD (cfg, mono_class_from_mono_type (t))) @@ -2669,7 +2669,11 @@ mono_codegen (MonoCompile *cfg) if (ji->type == MONO_PATCH_INFO_NONE) continue; - target = mono_resolve_patch_target (cfg->method, cfg->domain, cfg->native_code, ji, cfg->run_cctors); + target = mono_resolve_patch_target (cfg->method, cfg->domain, cfg->native_code, ji, cfg->run_cctors, &cfg->error); + if (!mono_error_ok (&cfg->error)) { + mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); + return; + } mono_arch_patch_code_new (cfg, cfg->domain, cfg->native_code, ji, target); } } @@ -2711,6 +2715,42 @@ compute_reachable (MonoBasicBlock *bb) } } +static void mono_bb_ordering (MonoCompile *cfg) +{ + int dfn = 0; + /* Depth-first ordering on basic blocks */ + cfg->bblocks = (MonoBasicBlock **)mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1)); + + cfg->max_block_num = cfg->num_bblocks; + + df_visit (cfg->bb_entry, &dfn, cfg->bblocks); + if (cfg->num_bblocks != dfn + 1) { + MonoBasicBlock *bb; + + cfg->num_bblocks = dfn + 1; + + /* remove unreachable code, because the code in them may be + * inconsistent (access to dead variables for example) */ + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) + bb->flags &= ~BB_VISITED; + compute_reachable (cfg->bb_entry); + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) + if (bb->flags & BB_EXCEPTION_HANDLER) + compute_reachable (bb); + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { + if (!(bb->flags & BB_VISITED)) { + if (cfg->verbose_level > 1) + g_print ("found unreachable code in BB%d\n", bb->block_num); + bb->code = bb->last_ins = NULL; + while (bb->out_count) + mono_unlink_bblock (cfg, bb, bb->out_bb [0]); + } + } + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) + bb->flags &= ~BB_VISITED; + } +} + static void mono_handle_out_of_line_bblock (MonoCompile *cfg) { @@ -2968,7 +3008,12 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile) */ ei->try_start = (guint8*)ei->try_start - cfg->backend->monitor_enter_adjustment; } - tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len]; + if (ec->try_offset + ec->try_len < header->code_size) + tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len]; + else + tblock = cfg->bb_exit; + if (G_UNLIKELY (cfg->verbose_level >= 4)) + printf ("looking for end of try [%d, %d] -> %p (code size %d)\n", ec->try_offset, ec->try_len, tblock, header->code_size); g_assert (tblock); if (!tblock->native_offset) { int j, end; @@ -3218,6 +3263,52 @@ mono_insert_safepoints (MonoCompile *cfg) } + +static void +mono_insert_branches_between_bblocks (MonoCompile *cfg) +{ + MonoBasicBlock *bb; + + /* Add branches between non-consecutive bblocks */ + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { + if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) && + bb->last_ins->inst_false_bb && bb->next_bb != bb->last_ins->inst_false_bb) { + /* we are careful when inverting, since bugs like #59580 + * could show up when dealing with NaNs. + */ + if (MONO_IS_COND_BRANCH_NOFP(bb->last_ins) && bb->next_bb == bb->last_ins->inst_true_bb) { + MonoBasicBlock *tmp = bb->last_ins->inst_true_bb; + bb->last_ins->inst_true_bb = bb->last_ins->inst_false_bb; + bb->last_ins->inst_false_bb = tmp; + + bb->last_ins->opcode = mono_reverse_branch_op (bb->last_ins->opcode); + } else { + MonoInst *inst = (MonoInst *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst)); + inst->opcode = OP_BR; + inst->inst_target_bb = bb->last_ins->inst_false_bb; + mono_bblock_add_inst (bb, inst); + } + } + } + + if (cfg->verbose_level >= 4) { + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { + MonoInst *tree = bb->code; + g_print ("DUMP BLOCK %d:\n", bb->block_num); + if (!tree) + continue; + for (; tree; tree = tree->next) { + mono_print_ins_index (-1, tree); + } + } + } + + /* FIXME: */ + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { + bb->max_vreg = cfg->next_vreg; + } +} + static void init_backend (MonoBackend *backend) { @@ -3301,7 +3392,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl MonoMethodSignature *sig; MonoError err; MonoCompile *cfg; - int dfn, i, code_size_ratio; + int i, code_size_ratio; gboolean try_generic_shared, try_llvm = FALSE; MonoMethod *method_to_compile, *method_to_register; gboolean method_is_gshared = FALSE; @@ -3379,7 +3470,6 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg = g_new0 (MonoCompile, 1); cfg->method = method_to_compile; - cfg->header = mono_method_get_header (cfg->method); cfg->mempool = mono_mempool_new (); cfg->opt = opts; cfg->prof_options = mono_profiler_get_events (); @@ -3388,6 +3478,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->verbose_level = mini_verbose; cfg->compile_aot = compile_aot; cfg->full_aot = full_aot; + cfg->disable_omit_fp = debug_options.disable_omit_fp; cfg->skip_visibility = method->skip_visibility; cfg->orig_method = method; cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_sdb_seq_points; @@ -3484,14 +3575,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl return cfg; } - header = cfg->header; + header = cfg->header = mono_method_get_header_checked (cfg->method, &cfg->error); if (!header) { - if (mono_loader_get_last_error ()) { - mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); - mono_error_set_from_loader_error (&cfg->error); - } else { - mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name)); - } + mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); if (MONO_METHOD_COMPILE_END_ENABLED ()) MONO_PROBE_METHOD_COMPILE_END (method, FALSE); return cfg; @@ -3647,7 +3733,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl */ mono_compile_create_vars (cfg); - i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, 0, FALSE); + MONO_TIME_TRACK (mono_jit_stats.jit_method_to_ir, i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, 0, FALSE)); if (i < 0) { if (try_generic_shared && cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) { @@ -3708,71 +3794,43 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl * This also allows SSA to be run on methods containing exception clauses, since * SSA will ignore variables marked VOLATILE. */ - mono_liveness_handle_exception_clauses (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_liveness_handle_exception_clauses, mono_liveness_handle_exception_clauses (cfg)); - mono_handle_out_of_line_bblock (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_handle_out_of_line_bblock, mono_handle_out_of_line_bblock (cfg)); /*g_print ("numblocks = %d\n", cfg->num_bblocks);*/ - if (!COMPILE_LLVM (cfg)) - mono_decompose_long_opts (cfg); + if (!COMPILE_LLVM (cfg)) { + MONO_TIME_TRACK (mono_jit_stats.jit_decompose_long_opts, mono_decompose_long_opts (cfg)); + } /* Should be done before branch opts */ if (cfg->opt & (MONO_OPT_CONSPROP | MONO_OPT_COPYPROP)) - mono_local_cprop (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_local_cprop, mono_local_cprop (cfg)); + /* * Should be done after cprop which can do strength reduction on * some of these ops, after propagating immediates. */ if (cfg->has_emulated_ops) - mono_local_emulate_ops (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_local_emulate_ops, mono_local_emulate_ops (cfg)); + if (cfg->opt & MONO_OPT_BRANCH) - mono_optimize_branches (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_optimize_branches, mono_optimize_branches (cfg)); /* This must be done _before_ global reg alloc and _after_ decompose */ - mono_handle_global_vregs (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_handle_global_vregs, mono_handle_global_vregs (cfg)); if (cfg->opt & MONO_OPT_DEADCE) - mono_local_deadce (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_local_deadce, mono_local_deadce (cfg)); if (cfg->opt & MONO_OPT_ALIAS_ANALYSIS) - mono_local_alias_analysis (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_local_alias_analysis, mono_local_alias_analysis (cfg)); /* Disable this for LLVM to make the IR easier to handle */ if (!COMPILE_LLVM (cfg)) - mono_if_conversion (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_if_conversion, mono_if_conversion (cfg)); mono_threads_safepoint (); - /* Depth-first ordering on basic blocks */ - cfg->bblocks = (MonoBasicBlock **)mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1)); - - cfg->max_block_num = cfg->num_bblocks; - - dfn = 0; - df_visit (cfg->bb_entry, &dfn, cfg->bblocks); - if (cfg->num_bblocks != dfn + 1) { - MonoBasicBlock *bb; - - cfg->num_bblocks = dfn + 1; - - /* remove unreachable code, because the code in them may be - * inconsistent (access to dead variables for example) */ - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) - bb->flags &= ~BB_VISITED; - compute_reachable (cfg->bb_entry); - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) - if (bb->flags & BB_EXCEPTION_HANDLER) - compute_reachable (bb); - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { - if (!(bb->flags & BB_VISITED)) { - if (cfg->verbose_level > 1) - g_print ("found unreachable code in BB%d\n", bb->block_num); - bb->code = bb->last_ins = NULL; - while (bb->out_count) - mono_unlink_bblock (cfg, bb, bb->out_bb [0]); - } - } - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) - bb->flags &= ~BB_VISITED; - } + MONO_TIME_TRACK (mono_jit_stats.jit_bb_ordering, mono_bb_ordering (cfg)); if (((cfg->num_varinfo > 2000) || (cfg->num_bblocks > 1000)) && !cfg->compile_aot) { /* @@ -3785,11 +3843,11 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl } if (cfg->opt & MONO_OPT_LOOP) { - mono_compile_dominator_info (cfg, MONO_COMP_DOM | MONO_COMP_IDOM); - mono_compute_natural_loops (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_compile_dominator_info, mono_compile_dominator_info (cfg, MONO_COMP_DOM | MONO_COMP_IDOM)); + MONO_TIME_TRACK (mono_jit_stats.jit_compute_natural_loops, mono_compute_natural_loops (cfg)); } - mono_insert_safepoints (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_insert_safepoints, mono_insert_safepoints (cfg)); /* after method_to_ir */ if (parts == 1) { @@ -3818,7 +3876,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl if (cfg->opt & MONO_OPT_SSA) { if (!(cfg->comp_done & MONO_COMP_SSA) && !cfg->disable_ssa) { #ifndef DISABLE_SSA - mono_ssa_compute (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_ssa_compute, mono_ssa_compute (cfg)); #endif if (cfg->verbose_level >= 2) { @@ -3838,7 +3896,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl if ((cfg->opt & MONO_OPT_CONSPROP) || (cfg->opt & MONO_OPT_COPYPROP)) { if (cfg->comp_done & MONO_COMP_SSA && !COMPILE_LLVM (cfg)) { #ifndef DISABLE_SSA - mono_ssa_cprop (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_ssa_cprop, mono_ssa_cprop (cfg)); #endif } } @@ -3848,19 +3906,19 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl //mono_ssa_strength_reduction (cfg); if (cfg->opt & MONO_OPT_DEADCE) - mono_ssa_deadce (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_ssa_deadce, mono_ssa_deadce (cfg)); if ((cfg->flags & (MONO_CFG_HAS_LDELEMA|MONO_CFG_HAS_CHECK_THIS)) && (cfg->opt & MONO_OPT_ABCREM)) - mono_perform_abc_removal (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_perform_abc_removal, mono_perform_abc_removal (cfg)); - mono_ssa_remove (cfg); - mono_local_cprop (cfg); - mono_handle_global_vregs (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_ssa_remove, mono_ssa_remove (cfg)); + MONO_TIME_TRACK (mono_jit_stats.jit_local_cprop2, mono_local_cprop (cfg)); + MONO_TIME_TRACK (mono_jit_stats.jit_handle_global_vregs2, mono_handle_global_vregs (cfg)); if (cfg->opt & MONO_OPT_DEADCE) - mono_local_deadce (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_local_deadce2, mono_local_deadce (cfg)); if (cfg->opt & MONO_OPT_BRANCH) - mono_optimize_branches (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_optimize_branches2, mono_optimize_branches (cfg)); } #endif @@ -3885,9 +3943,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl if (COMPILE_SOFT_FLOAT (cfg)) mono_decompose_soft_float (cfg); #endif - mono_decompose_vtype_opts (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_decompose_vtype_opts, mono_decompose_vtype_opts (cfg)); if (cfg->flags & MONO_CFG_HAS_ARRAY_ACCESS) - mono_decompose_array_access_opts (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_decompose_array_access_opts, mono_decompose_array_access_opts (cfg)); if (cfg->got_var) { #ifndef MONO_ARCH_GOT_REG @@ -3920,7 +3978,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl /* * Have to call this again to process variables added since the first call. */ - mono_liveness_handle_exception_clauses (cfg); + MONO_TIME_TRACK(mono_jit_stats.jit_liveness_handle_exception_clauses2, mono_liveness_handle_exception_clauses (cfg)); if (cfg->opt & MONO_OPT_LINEARS) { GList *vars, *regs, *l; @@ -3928,7 +3986,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl /* fixme: maybe we can avoid to compute livenesss here if already computed ? */ cfg->comp_done &= ~MONO_COMP_LIVENESS; if (!(cfg->comp_done & MONO_COMP_LIVENESS)) - mono_analyze_liveness (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_analyze_liveness, mono_analyze_liveness (cfg)); if ((vars = mono_arch_get_allocatable_int_vars (cfg))) { regs = mono_arch_get_global_int_regs (cfg); @@ -3941,7 +3999,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl } } } - mono_linear_scan (cfg, vars, regs, &cfg->used_int_regs); + MONO_TIME_TRACK (mono_jit_stats.jit_linear_scan, mono_linear_scan (cfg, vars, regs, &cfg->used_int_regs)); } } @@ -3951,69 +4009,28 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl /* variables are allocated after decompose, since decompose could create temps */ if (!COMPILE_LLVM (cfg)) { - mono_arch_allocate_vars (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_arch_allocate_vars, mono_arch_allocate_vars (cfg)); if (cfg->exception_type) return cfg; } - { - MonoBasicBlock *bb; - gboolean need_local_opts; - - if (cfg->gsharedvt) - mono_allocate_gsharedvt_vars (cfg); - - if (!COMPILE_LLVM (cfg)) { - mono_spill_global_vars (cfg, &need_local_opts); - - if (need_local_opts || cfg->compile_aot) { - /* To optimize code created by spill_global_vars */ - mono_local_cprop (cfg); - if (cfg->opt & MONO_OPT_DEADCE) - mono_local_deadce (cfg); - } - } - - /* Add branches between non-consecutive bblocks */ - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { - if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) && - bb->last_ins->inst_false_bb && bb->next_bb != bb->last_ins->inst_false_bb) { - /* we are careful when inverting, since bugs like #59580 - * could show up when dealing with NaNs. - */ - if (MONO_IS_COND_BRANCH_NOFP(bb->last_ins) && bb->next_bb == bb->last_ins->inst_true_bb) { - MonoBasicBlock *tmp = bb->last_ins->inst_true_bb; - bb->last_ins->inst_true_bb = bb->last_ins->inst_false_bb; - bb->last_ins->inst_false_bb = tmp; - - bb->last_ins->opcode = mono_reverse_branch_op (bb->last_ins->opcode); - } else { - MonoInst *inst = (MonoInst *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst)); - inst->opcode = OP_BR; - inst->inst_target_bb = bb->last_ins->inst_false_bb; - mono_bblock_add_inst (bb, inst); - } - } - } + if (cfg->gsharedvt) + mono_allocate_gsharedvt_vars (cfg); - if (cfg->verbose_level >= 4) { - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { - MonoInst *tree = bb->code; - g_print ("DUMP BLOCK %d:\n", bb->block_num); - if (!tree) - continue; - for (; tree; tree = tree->next) { - mono_print_ins_index (-1, tree); - } - } - } + if (!COMPILE_LLVM (cfg)) { + gboolean need_local_opts; + MONO_TIME_TRACK (mono_jit_stats.jit_spill_global_vars, mono_spill_global_vars (cfg, &need_local_opts)); - /* FIXME: */ - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { - bb->max_vreg = cfg->next_vreg; + if (need_local_opts || cfg->compile_aot) { + /* To optimize code created by spill_global_vars */ + MONO_TIME_TRACK (mono_jit_stats.jit_local_cprop3, mono_local_cprop (cfg)); + if (cfg->opt & MONO_OPT_DEADCE) + MONO_TIME_TRACK (mono_jit_stats.jit_local_deadce3, mono_local_deadce (cfg)); } } + mono_insert_branches_between_bblocks (cfg); + if (COMPILE_LLVM (cfg)) { #ifdef ENABLE_LLVM char *nm; @@ -4053,7 +4070,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl } #endif } else { - mono_codegen (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_codegen, mono_codegen (cfg)); + if (cfg->exception_type) + return cfg; } if (COMPILE_LLVM (cfg)) @@ -4061,7 +4080,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl else InterlockedIncrement (&mono_jit_stats.methods_without_llvm); - cfg->jit_info = create_jit_info (cfg, method_to_compile); + MONO_TIME_TRACK (mono_jit_stats.jit_create_jit_info, cfg->jit_info = create_jit_info (cfg, method_to_compile)); #ifdef MONO_ARCH_HAVE_LIVERANGE_OPS if (cfg->extend_live_ranges) { @@ -4074,9 +4093,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl if (!cfg->compile_aot) mono_save_xdebug_info (cfg); - mini_gc_create_gc_map (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_gc_create_gc_map, mini_gc_create_gc_map (cfg)); - mono_save_seq_point_info (cfg); + MONO_TIME_TRACK (mono_jit_stats.jit_save_seq_point_info, mono_save_seq_point_info (cfg)); if (cfg->verbose_level >= 2) { char *id = mono_method_full_name (cfg->method, FALSE); @@ -4184,6 +4203,31 @@ create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info) return jinfo; } +GTimer *mono_time_track_start () +{ + return g_timer_new (); +} + +void mono_time_track_end (double *time, GTimer *timer) +{ + g_timer_stop (timer); + *time += g_timer_elapsed (timer, NULL); + g_timer_destroy (timer); +} + +void mono_update_jit_stats (MonoCompile *cfg) +{ + mono_jit_stats.allocate_var += cfg->stat_allocate_var; + mono_jit_stats.locals_stack_size += cfg->stat_locals_stack_size; + mono_jit_stats.basic_blocks += cfg->stat_basic_blocks; + mono_jit_stats.max_basic_blocks = MAX (cfg->stat_basic_blocks, mono_jit_stats.max_basic_blocks); + mono_jit_stats.cil_code_size += cfg->stat_cil_code_size; + mono_jit_stats.regvars += cfg->stat_n_regvars; + mono_jit_stats.inlineable_methods += cfg->stat_inlineable_methods; + mono_jit_stats.inlined_methods += cfg->stat_inlined_methods; + mono_jit_stats.code_reallocs += cfg->stat_code_reallocs; +} + /* * mono_jit_compile_method_inner: * @@ -4317,14 +4361,11 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in return NULL; } - jit_timer = g_timer_new (); - + jit_timer = mono_time_track_start (); cfg = mini_method_compile (method, opt, target_domain, JIT_FLAG_RUN_CCTORS, 0, -1); - prof_method = cfg->method; + mono_time_track_end (&mono_jit_stats.jit_time, jit_timer); - g_timer_stop (jit_timer); - mono_jit_stats.jit_time += g_timer_elapsed (jit_timer, NULL); - g_timer_destroy (jit_timer); + prof_method = cfg->method; switch (cfg->exception_type) { case MONO_EXCEPTION_NONE: @@ -4412,15 +4453,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in * Update global stats while holding a lock, instead of doing many * InterlockedIncrement operations during JITting. */ - mono_jit_stats.allocate_var += cfg->stat_allocate_var; - mono_jit_stats.locals_stack_size += cfg->stat_locals_stack_size; - mono_jit_stats.basic_blocks += cfg->stat_basic_blocks; - mono_jit_stats.max_basic_blocks = MAX (cfg->stat_basic_blocks, mono_jit_stats.max_basic_blocks); - mono_jit_stats.cil_code_size += cfg->stat_cil_code_size; - mono_jit_stats.regvars += cfg->stat_n_regvars; - mono_jit_stats.inlineable_methods += cfg->stat_inlineable_methods; - mono_jit_stats.inlined_methods += cfg->stat_inlined_methods; - mono_jit_stats.code_reallocs += cfg->stat_code_reallocs; + mono_update_jit_stats (cfg); mono_destroy_compile (cfg); @@ -4443,7 +4476,9 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in #endif #ifdef MONO_ARCH_HAVE_PATCH_CODE_NEW for (tmp = jlist->list; tmp; tmp = tmp->next) { - gpointer target = mono_resolve_patch_target (NULL, target_domain, (guint8 *)tmp->data, &patch_info, TRUE); + gpointer target = mono_resolve_patch_target (NULL, target_domain, (guint8 *)tmp->data, &patch_info, TRUE, error); + if (!mono_error_ok (error)) + break; mono_arch_patch_code_new (NULL, target_domain, (guint8 *)tmp->data, &patch_info, target); } #else @@ -4456,10 +4491,25 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in } } + /* Update llvm callees */ + if (domain_jit_info (target_domain)->llvm_jit_callees) { + GSList *callees = g_hash_table_lookup (domain_jit_info (target_domain)->llvm_jit_callees, method); + GSList *l; + + for (l = callees; l; l = l->next) { + gpointer *addr = (gpointer*)l->data; + + *addr = code; + } + } + mono_emit_jit_map (jinfo); #endif mono_domain_unlock (target_domain); + if (!mono_error_ok (error)) + return NULL; + vtable = mono_class_vtable (target_domain, method->klass); if (!vtable) { ex = mono_class_get_exception_for_failure (method->klass); @@ -4482,11 +4532,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in } } - ex = mono_runtime_class_init_full (vtable, FALSE); - if (ex) { - mono_error_set_exception_instance (error, ex); + if (!mono_runtime_class_init_full (vtable, error)) return NULL; - } return code; }