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) {
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);
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)))
#endif
if (cfg->verbose_level > 0) {
- char* nm = mono_method_full_name (cfg->method, TRUE);
+ char* nm = mono_method_get_full_name (cfg->method);
char *opt_descr = mono_opt_descr (cfg->opt);
g_print ("Method %s emitted at %p to %p (code length %d) [%s] with opts %s\n",
nm,
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);
}
}
}
}
+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)
{
*/
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;
}
+
+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)
{
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;
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 ();
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;
if (cfg->verbose_level > 0) {
char *method_name;
- method_name = mono_method_full_name (method, TRUE);
+ method_name = mono_method_get_full_name (method);
g_print ("converting %s%s%smethod %s\n", COMPILE_LLVM (cfg) ? "llvm " : "", cfg->gsharedvt ? "gsharedvt " : "", (cfg->gshared && !cfg->gsharedvt) ? "gshared " : "", method_name);
/*
if (COMPILE_LLVM (cfg))
*/
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) {
* 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) {
/*
}
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) {
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) {
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
}
}
//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
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
/*
* 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;
/* 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);
}
}
}
- 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));
}
}
/* 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;
}
#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))
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) {
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);
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:
*
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:
* 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);
#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
#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);
}
}
- 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;
}