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);
+ mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", "%s", msg);
if (!mono_error_ok (&cfg->error)) {
mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
g_free (msg);
vars = g_list_prepend (vars, vmv);
}
- vars = g_list_sort (g_list_copy (vars), compare_by_interval_start_pos_func);
+ vars = g_list_sort (vars, compare_by_interval_start_pos_func);
/* Sanity check */
/*
mono_verify_bblock (bb);
}
+// This will free many fields in cfg to save
+// memory. Note that this must be safe to call
+// multiple times. It must be idempotent.
+void
+mono_empty_compile (MonoCompile *cfg)
+{
+ mono_free_loop_info (cfg);
+
+ // These live in the mempool, and so must be freed
+ // first
+ for (GSList *l = cfg->headers_to_free; l; l = l->next) {
+ mono_metadata_free_mh ((MonoMethodHeader *)l->data);
+ }
+ cfg->headers_to_free = NULL;
+
+ if (cfg->mempool) {
+ //mono_mempool_stats (cfg->mempool);
+ mono_mempool_destroy (cfg->mempool);
+ cfg->mempool = NULL;
+ }
+
+ g_free (cfg->varinfo);
+ cfg->varinfo = NULL;
+
+ g_free (cfg->vars);
+ cfg->vars = NULL;
+
+ if (cfg->rs) {
+ mono_regstate_free (cfg->rs);
+ cfg->rs = NULL;
+ }
+}
+
void
mono_destroy_compile (MonoCompile *cfg)
{
- GSList *l;
+ mono_empty_compile (cfg);
if (cfg->header)
mono_metadata_free_mh (cfg->header);
- //mono_mempool_stats (cfg->mempool);
- mono_free_loop_info (cfg);
- if (cfg->rs)
- mono_regstate_free (cfg->rs);
+
if (cfg->spvars)
g_hash_table_destroy (cfg->spvars);
if (cfg->exvars)
g_hash_table_destroy (cfg->exvars);
- for (l = cfg->headers_to_free; l; l = l->next)
- mono_metadata_free_mh ((MonoMethodHeader *)l->data);
+
g_list_free (cfg->ldstr_list);
- g_hash_table_destroy (cfg->token_info_hash);
+
+ if (cfg->token_info_hash)
+ g_hash_table_destroy (cfg->token_info_hash);
+
if (cfg->abs_patches)
g_hash_table_destroy (cfg->abs_patches);
- mono_mempool_destroy (cfg->mempool);
mono_debug_free_method (cfg);
if (!cfg->backend->have_tls_get)
return NULL;
+#ifdef HAVE_KW_THREAD
+ /*
+ * MONO_THREAD_VAR_OFFSET definitions don't work when loading mono as a
+ * dynamic library. This means that we need to be conservative and don't
+ * aot code that contains these tls chunks.
+ *
+ * FIXME Remove HAVE_KW_THREAD altogether and use only pthread since it
+ * simplifies the code alot.
+ */
+ if (!cfg->full_aot)
+ cfg->disable_aot = TRUE;
+#endif
/*
* TLS offsets might be different at AOT time, so load them from a GOT slot and
* use a different opcode.
#ifdef MONO_ARCH_HAVE_OBJC_GET_SELECTOR
backend->have_objc_get_selector = 1;
#endif
-#ifdef MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK
- backend->have_generalized_imt_thunk = 1;
+#ifdef MONO_ARCH_HAVE_GENERALIZED_IMT_TRAMPOLINE
+ backend->have_generalized_imt_trampoline = 1;
#endif
#ifdef MONO_ARCH_GSHARED_SUPPORTED
backend->gshared_supported = 1;
#ifdef MONO_ARCH_DYN_CALL_PARAM_AREA
backend->dyn_call_param_area = MONO_ARCH_DYN_CALL_PARAM_AREA;
#endif
+#ifdef MONO_ARCH_NO_DIV_WITH_MUL
+ backend->disable_div_with_mul = 1;
+#endif
}
/*
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;
+ cfg->gen_seq_points = !debug_options.no_seq_points_compact_data || debug_options.gen_sdb_seq_points;
cfg->gen_sdb_seq_points = debug_options.gen_sdb_seq_points;
cfg->llvm_only = (flags & JIT_FLAG_LLVM_ONLY) != 0;
cfg->backend = current_backend;
cfg->gen_sdb_seq_points = FALSE;
}
#endif
+ if (cfg->method->wrapper_type == MONO_WRAPPER_ALLOC) {
+ /* We can't have seq points inside gc critical regions */
+ cfg->gen_seq_points = FALSE;
+ cfg->gen_sdb_seq_points = FALSE;
+ }
/* coop / nacl requires loop detection to happen */
#if defined(__native_client_codegen__)
cfg->opt |= MONO_OPT_LOOP;
//g_free (nm);
}
if (cfg->llvm_only) {
+ g_free (cfg->exception_message);
cfg->disable_aot = TRUE;
return cfg;
}
mono_cfg_dump_ir (cfg, "local_cprop");
}
- MONO_TIME_TRACK (mono_jit_stats.jit_decompose_typechecks, mono_decompose_typechecks (cfg));
- if (cfg->gdump_ctx != NULL) {
- /* workaround for graph visualization, as it doesn't handle empty basic blocks properly */
- mono_insert_nop_in_empty_bb (cfg);
+ if (cfg->flags & MONO_CFG_HAS_TYPE_CHECK) {
+ MONO_TIME_TRACK (mono_jit_stats.jit_decompose_typechecks, mono_decompose_typechecks (cfg));
+ if (cfg->gdump_ctx != NULL) {
+ /* workaround for graph visualization, as it doesn't handle empty basic blocks properly */
+ mono_insert_nop_in_empty_bb (cfg);
+ }
+ mono_cfg_dump_ir (cfg, "decompose_typechecks");
}
- mono_cfg_dump_ir (cfg, "decompose_typechecks");
/*
* Should be done after cprop which can do strength reduction on
mono_cfg_set_exception_invalid_program (MonoCompile *cfg, char *msg)
{
mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
- mono_error_set_generic_error (&cfg->error, "System", "InvalidProgramException", msg);
+ mono_error_set_generic_error (&cfg->error, "System", "InvalidProgramException", "%s", msg);
}
#endif /* DISABLE_JIT */
if (mono_aot_only) {
char *fullname = mono_method_full_name (method, TRUE);
- char *msg = g_strdup_printf ("Attempting to JIT compile method '%s' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.\n", fullname);
-
- ex = mono_get_exception_execution_engine (msg);
- mono_error_set_exception_instance (error, ex);
+ mono_error_set_execution_engine (error, "Attempting to JIT compile method '%s' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.\n", fullname);
g_free (fullname);
- g_free (msg);
-
+
return NULL;
}
vtable = mono_class_vtable (target_domain, method->klass);
if (!vtable) {
- ex = mono_class_get_exception_for_failure (method->klass);
- g_assert (ex);
- mono_error_set_exception_instance (error, ex);
+ g_assert (mono_class_has_failure (method->klass));
+ mono_error_set_for_class_failure (error, method->klass);
return NULL;
}