#include <mono/utils/mono-math.h>
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-counters.h>
+#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-path.h>
#include <mono/utils/mono-threads.h>
#include "mini.h"
+#include "seq-points.h"
#include "mini-llvm.h"
#include "tasklets.h"
#include <string.h>
#include "mini-gc.h"
#include "debugger-agent.h"
+#include "seq-points.h"
static gpointer mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex);
mono_debug_count (void)
{
static int count = 0;
+ static gboolean inited;
+ static const char *value;
+
count ++;
- if (!g_getenv ("COUNT"))
+ if (!inited) {
+ value = g_getenv ("COUNT");
+ inited = TRUE;
+ }
+
+ if (!value)
return TRUE;
- if (count == atoi (g_getenv ("COUNT"))) {
+ if (count == atoi (value))
break_count ();
- }
- if (count > atoi (g_getenv ("COUNT"))) {
+ if (count > atoi (value))
return FALSE;
- }
return TRUE;
}
if ((num + 1) >= cfg->varinfo_count) {
int orig_count = cfg->varinfo_count;
- cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 64;
+ cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 32;
cfg->varinfo = (MonoInst **)g_realloc (cfg->varinfo, sizeof (MonoInst*) * cfg->varinfo_count);
cfg->vars = (MonoMethodVar *)g_realloc (cfg->vars, sizeof (MonoMethodVar) * cfg->varinfo_count);
memset (&cfg->vars [orig_count], 0, (cfg->varinfo_count - orig_count) * sizeof (MonoMethodVar));
#endif
#endif
-MonoNativeTlsKey
-mono_get_jit_tls_key (void)
-{
- return mono_jit_tls_id;
-}
-
gint32
mono_get_jit_tls_offset (void)
{
int offset;
+
+#ifdef HOST_WIN32
+ if (mono_jit_tls_id)
+ offset = mono_jit_tls_id;
+ else
+ /* FIXME: Happens during startup */
+ offset = -1;
+#else
MONO_THREAD_VAR_OFFSET (mono_jit_tls, offset);
+#endif
return offset;
}
offset = mono_thread_get_tls_offset ();
break;
case TLS_KEY_JIT_TLS:
-#ifdef HOST_WIN32
- offset = mono_get_jit_tls_key ();
-#else
offset = mono_get_jit_tls_offset ();
-#endif
break;
case TLS_KEY_DOMAIN:
offset = mono_domain_get_tls_offset ();
case MONO_PATCH_INFO_JIT_TLS_ID:
case MONO_PATCH_INFO_MONITOR_ENTER:
case MONO_PATCH_INFO_MONITOR_EXIT:
- case MONO_PATCH_INFO_CASTCLASS_CACHE:
case MONO_PATCH_INFO_GOT_OFFSET:
return (ji->type << 8);
+ case MONO_PATCH_INFO_CASTCLASS_CACHE:
+ return (ji->type << 8) | (ji->data.index);
case MONO_PATCH_INFO_SWITCH:
return (ji->type << 8) | ji->data.table->table_size;
case MONO_PATCH_INFO_GSHAREDVT_METHOD:
return ji1->data.gsharedvt_method->method == ji2->data.gsharedvt_method->method;
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
return ji1->data.del_tramp->klass == ji2->data.del_tramp->klass && ji1->data.del_tramp->method == ji2->data.del_tramp->method && ji1->data.del_tramp->virtual == ji2->data.del_tramp->virtual;
+ case MONO_PATCH_INFO_CASTCLASS_CACHE:
+ return ji1->data.index == ji2->data.index;
default:
if (ji1->data.target != ji2->data.target)
return 0;
}
}
-static void
-collect_pred_seq_points (MonoBasicBlock *bb, MonoInst *ins, GSList **next, int depth)
-{
- int i;
- MonoBasicBlock *in_bb;
- GSList *l;
-
- for (i = 0; i < bb->in_count; ++i) {
- in_bb = bb->in_bb [i];
-
- if (in_bb->last_seq_point) {
- int src_index = in_bb->last_seq_point->backend.size;
- int dst_index = ins->backend.size;
-
- /* bb->in_bb might contain duplicates */
- for (l = next [src_index]; l; l = l->next)
- if (GPOINTER_TO_UINT (l->data) == dst_index)
- break;
- if (!l)
- next [src_index] = g_slist_append (next [src_index], GUINT_TO_POINTER (dst_index));
- } else {
- /* Have to look at its predecessors */
- if (depth < 5)
- collect_pred_seq_points (in_bb, ins, next, depth + 1);
- }
- }
-}
-
-static void
-mono_save_seq_point_info (MonoCompile *cfg)
-{
- MonoBasicBlock *bb;
- GSList *bb_seq_points, *l;
- MonoInst *last;
- MonoDomain *domain = cfg->domain;
- int i;
- MonoSeqPointInfo *info;
- GSList **next;
-
- if (!cfg->seq_points)
- return;
-
- info = g_malloc0 (sizeof (MonoSeqPointInfo) + (cfg->seq_points->len * sizeof (SeqPoint)));
- info->len = cfg->seq_points->len;
- for (i = 0; i < cfg->seq_points->len; ++i) {
- SeqPoint *sp = &info->seq_points [i];
- MonoInst *ins = g_ptr_array_index (cfg->seq_points, i);
-
- sp->il_offset = ins->inst_imm;
- sp->native_offset = ins->inst_offset;
- if (ins->flags & MONO_INST_NONEMPTY_STACK)
- sp->flags |= MONO_SEQ_POINT_FLAG_NONEMPTY_STACK;
-
- /* Used below */
- ins->backend.size = i;
- }
-
- /*
- * For each sequence point, compute the list of sequence points immediately
- * following it, this is needed to implement 'step over' in the debugger agent.
- */
- next = g_new0 (GSList*, cfg->seq_points->len);
- for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
- bb_seq_points = g_slist_reverse (bb->seq_points);
- last = NULL;
- for (l = bb_seq_points; l; l = l->next) {
- MonoInst *ins = l->data;
-
- if (ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET)
- /* Used to implement method entry/exit events */
- continue;
- if (ins->inst_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE)
- continue;
-
- if (last != NULL) {
- /* Link with the previous seq point in the same bb */
- next [last->backend.size] = g_slist_append (next [last->backend.size], GUINT_TO_POINTER (ins->backend.size));
- } else {
- /* Link with the last bb in the previous bblocks */
- collect_pred_seq_points (bb, ins, next, 0);
- }
-
- last = ins;
- }
-
- if (bb->last_ins && bb->last_ins->opcode == OP_ENDFINALLY && bb->seq_points) {
- MonoBasicBlock *bb2;
- MonoInst *endfinally_seq_point = NULL;
-
- /*
- * The ENDFINALLY branches are not represented in the cfg, so link it with all seq points starting bbs.
- */
- l = g_slist_last (bb->seq_points);
- if (l) {
- endfinally_seq_point = l->data;
-
- for (bb2 = cfg->bb_entry; bb2; bb2 = bb2->next_bb) {
- GSList *l = g_slist_last (bb2->seq_points);
-
- if (l) {
- MonoInst *ins = l->data;
-
- if (!(ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET) && ins != endfinally_seq_point)
- next [endfinally_seq_point->backend.size] = g_slist_append (next [endfinally_seq_point->backend.size], GUINT_TO_POINTER (ins->backend.size));
- }
- }
- }
- }
- }
-
- if (cfg->verbose_level > 2) {
- printf ("\nSEQ POINT MAP: \n");
- }
-
- for (i = 0; i < cfg->seq_points->len; ++i) {
- SeqPoint *sp = &info->seq_points [i];
- GSList *l;
- int j, next_index;
-
- sp->next_len = g_slist_length (next [i]);
- sp->next = g_new (int, sp->next_len);
- j = 0;
- if (cfg->verbose_level > 2 && next [i]) {
- printf ("\tIL0x%x ->", sp->il_offset);
- for (l = next [i]; l; l = l->next) {
- next_index = GPOINTER_TO_UINT (l->data);
- printf (" IL0x%x", info->seq_points [next_index].il_offset);
- }
- printf ("\n");
- }
- for (l = next [i]; l; l = l->next) {
- next_index = GPOINTER_TO_UINT (l->data);
- sp->next [j ++] = next_index;
- }
- g_slist_free (next [i]);
- }
- g_free (next);
-
- cfg->seq_point_info = info;
-
- // FIXME: dynamic methods
- if (!cfg->compile_aot) {
- mono_domain_lock (domain);
- // FIXME: How can the lookup succeed ?
- if (!g_hash_table_lookup (domain_jit_info (domain)->seq_points, cfg->method_to_register))
- g_hash_table_insert (domain_jit_info (domain)->seq_points, cfg->method_to_register, info);
- mono_domain_unlock (domain);
- }
-
- g_ptr_array_free (cfg->seq_points, TRUE);
- cfg->seq_points = NULL;
-}
-
void
mono_codegen (MonoCompile *cfg)
{
cfg->code_len = code - cfg->native_code;
cfg->prolog_end = cfg->code_len;
+ cfg->cfa_reg = cfg->cur_cfa_reg;
+ cfg->cfa_offset = cfg->cur_cfa_offset;
mono_debug_open_method (cfg);
if (bb == cfg->bb_exit) {
cfg->epilog_begin = cfg->code_len;
mono_arch_emit_epilog (cfg);
+ cfg->epilog_end = cfg->code_len;
}
}
GSList *tmp;
MonoMethodHeader *header;
MonoJitInfo *jinfo;
- int num_clauses;
- int generic_info_size, arch_eh_info_size = 0;
- int holes_size = 0, num_holes = 0, cas_size = 0;
+ MonoJitInfoFlags flags = JIT_INFO_NONE;
+ int num_clauses, num_holes = 0;
guint32 stack_size = 0;
g_assert (method_to_compile == cfg->method);
header = cfg->header;
if (cfg->generic_sharing_context)
- generic_info_size = sizeof (MonoGenericJitInfo);
- else
- generic_info_size = 0;
+ flags |= JIT_INFO_HAS_GENERIC_JIT_INFO;
if (cfg->arch_eh_jit_info) {
MonoJitArgumentInfo *arg_info;
stack_size = mono_arch_get_argument_info (cfg->generic_sharing_context, sig, sig->param_count, arg_info);
if (stack_size)
- arch_eh_info_size = sizeof (MonoArchEHJitInfo);
+ flags |= JIT_INFO_HAS_ARCH_EH_INFO;
}
- if (cfg->has_unwind_info_for_epilog && !arch_eh_info_size)
- arch_eh_info_size = sizeof (MonoArchEHJitInfo);
+ if (cfg->has_unwind_info_for_epilog && !(flags & JIT_INFO_HAS_ARCH_EH_INFO))
+ flags |= JIT_INFO_HAS_ARCH_EH_INFO;
if (cfg->try_block_holes) {
for (tmp = cfg->try_block_holes; tmp; tmp = tmp->next) {
++num_holes;
}
if (num_holes)
- holes_size = sizeof (MonoTryBlockHoleTableJitInfo) + num_holes * sizeof (MonoTryBlockHoleJitInfo);
+ flags |= JIT_INFO_HAS_TRY_BLOCK_HOLES;
if (G_UNLIKELY (cfg->verbose_level >= 4))
printf ("Number of try block holes %d\n", num_holes);
}
- if (mono_security_method_has_declsec (cfg->method_to_register)) {
- cas_size = sizeof (MonoMethodCasInfo);
- }
+ if (mono_security_method_has_declsec (cfg->method_to_register))
+ flags |= JIT_INFO_HAS_ARCH_EH_INFO;
if (COMPILE_LLVM (cfg))
num_clauses = cfg->llvm_ex_info_len;
else
num_clauses = header->num_clauses;
- if (cfg->method->dynamic) {
- jinfo = g_malloc0 (MONO_SIZEOF_JIT_INFO + (num_clauses * sizeof (MonoJitExceptionInfo)) +
- generic_info_size + holes_size + arch_eh_info_size + cas_size);
- } else {
- jinfo = mono_domain_alloc0 (cfg->domain, MONO_SIZEOF_JIT_INFO +
- (num_clauses * sizeof (MonoJitExceptionInfo)) +
- generic_info_size + holes_size + arch_eh_info_size + cas_size);
- }
-
- jinfo->d.method = cfg->method_to_register;
- jinfo->code_start = cfg->native_code;
- jinfo->code_size = cfg->code_len;
+ if (cfg->method->dynamic)
+ jinfo = g_malloc0 (mono_jit_info_size (flags, num_clauses, num_holes));
+ else
+ jinfo = mono_domain_alloc0 (cfg->domain, mono_jit_info_size (flags, num_clauses, num_holes));
+ mono_jit_info_init (jinfo, cfg->method_to_register, cfg->native_code, cfg->code_len, flags, num_clauses, num_holes);
jinfo->domain_neutral = (cfg->opt & MONO_OPT_SHARED) != 0;
- jinfo->num_clauses = num_clauses;
if (COMPILE_LLVM (cfg))
jinfo->from_llvm = TRUE;
MonoGenericJitInfo *gi;
GSList *loclist = NULL;
- jinfo->has_generic_jit_info = 1;
-
gi = mono_jit_info_get_generic_jit_info (jinfo);
g_assert (gi);
MonoTryBlockHoleTableJitInfo *table;
int i;
- jinfo->has_try_block_holes = 1;
table = mono_jit_info_get_try_block_hole_table_info (jinfo);
table->num_holes = (guint16)num_holes;
i = 0;
g_assert (i == num_holes);
}
- if (arch_eh_info_size) {
+ if (jinfo->has_arch_eh_info) {
MonoArchEHJitInfo *info;
- jinfo->has_arch_eh_info = 1;
info = mono_jit_info_get_arch_eh_info (jinfo);
info->stack_size = stack_size;
}
- if (cas_size) {
- jinfo->has_cas_info = 1;
- }
-
if (COMPILE_LLVM (cfg)) {
if (num_clauses)
memcpy (&jinfo->clauses [0], &cfg->llvm_ex_info [0], num_clauses * sizeof (MonoJitExceptionInfo));
info = mono_jit_info_get_arch_eh_info (jinfo);
g_assert (info);
- info->epilog_size = cfg->code_size - cfg->epilog_begin;
+ info->epilog_size = cfg->code_len - cfg->epilog_begin;
}
jinfo->unwind_info = unwind_desc;
g_free (unwind_info);
gboolean run_cctors = (flags & JIT_FLAG_RUN_CCTORS) ? 1 : 0;
gboolean compile_aot = (flags & JIT_FLAG_AOT) ? 1 : 0;
gboolean full_aot = (flags & JIT_FLAG_FULL_AOT) ? 1 : 0;
+#ifdef ENABLE_LLVM
+ gboolean llvm = (flags & JIT_FLAG_LLVM) ? 1 : 0;
+#endif
+ static gboolean verbose_method_inited;
+ static const char *verbose_method_name;
InterlockedIncrement (&mono_jit_stats.methods_compiled);
if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION)
}
#ifdef ENABLE_LLVM
- try_llvm = mono_use_llvm;
+ try_llvm = mono_use_llvm || llvm;
#endif
restart_compile:
cfg->full_aot = full_aot;
cfg->skip_visibility = method->skip_visibility;
cfg->orig_method = method;
- cfg->gen_seq_points = debug_options.gen_seq_points;
+ cfg->gen_seq_points = TRUE;
+ cfg->gen_seq_points_debug_data = debug_options.gen_seq_points_debug_data;
+
cfg->explicit_null_checks = debug_options.explicit_null_checks;
cfg->soft_breakpoints = debug_options.soft_breakpoints;
cfg->check_pinvoke_callconv = debug_options.check_pinvoke_callconv;
if (cfg->gen_seq_points)
cfg->seq_points = g_ptr_array_new ();
+ mono_error_init (&cfg->error);
if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container || method_is_gshared)) {
cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED;
if (cfg->generic_sharing_context) {
method_to_register = method_to_compile;
+ cfg->gshared = TRUE;
} else {
g_assert (method == method_to_compile);
method_to_register = method;
{
static gboolean inited;
- if (!inited) {
+ if (!inited)
inited = TRUE;
- }
/*
* Check for methods which cannot be compiled by LLVM early, to avoid
cfg->opt |= MONO_OPT_ABCREM;
}
- if (g_getenv ("MONO_VERBOSE_METHOD")) {
- const char *name = g_getenv ("MONO_VERBOSE_METHOD");
+ if (!verbose_method_inited) {
+ verbose_method_name = g_getenv ("MONO_VERBOSE_METHOD");
+ verbose_method_inited = TRUE;
+ }
+ if (verbose_method_name) {
+ const char *name = verbose_method_name;
if ((strchr (name, '.') > name) || strchr (name, ':')) {
MonoMethodDesc *desc;
}
mono_method_desc_free (desc);
} else {
- if (strcmp (cfg->method->name, g_getenv ("MONO_VERBOSE_METHOD")) == 0)
+ if (strcmp (cfg->method->name, name) == 0)
cfg->verbose_level = 4;
}
}
/* SSAPRE is not supported on linear IR */
cfg->opt &= ~MONO_OPT_SSAPRE;
- i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, NULL, 0, FALSE);
+ 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) {
*/
//#define DEBUGSSA "logic_run"
-#define DEBUGSSA_CLASS "Tests"
+//#define DEBUGSSA_CLASS "Tests"
#ifdef DEBUGSSA
if (!cfg->disable_ssa) {
case MONO_EXCEPTION_OUT_OF_MEMORY:
ex = mono_domain_get ()->out_of_memory_ex;
break;
+ case MONO_EXCEPTION_MONO_ERROR:
+ g_assert (!mono_error_ok (&cfg->error));
+ ex = mono_error_convert_to_exception (&cfg->error);
+ break;
default:
g_assert_not_reached ();
}
return runtime_invoke (obj, params, exc, info->compiled_method);
}
-SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
{
MonoException *exc = NULL;
MonoJitInfo *ji;
-#if !(defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32))
- void *info = NULL;
-#endif
- GET_CONTEXT;
+ void *info = MONO_SIG_HANDLER_GET_INFO ();
+ MONO_SIG_HANDLER_GET_CONTEXT;
ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
#endif
if (!ji) {
- if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS))
+ if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
mono_handle_native_sigsegv (SIGSEGV, ctx);
if (mono_do_crash_chaining) {
- mono_chain_signal (SIG_HANDLER_PARAMS);
+ mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
return;
}
}
mono_arch_handle_exception (ctx, exc);
}
-SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
{
MonoException *exc;
- GET_CONTEXT;
+ MONO_SIG_HANDLER_GET_CONTEXT;
exc = mono_get_exception_execution_engine ("SIGILL");
#define HAVE_SIG_INFO
#endif
-SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
{
MonoJitInfo *ji;
MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
gpointer fault_addr = NULL;
-
- GET_CONTEXT;
+#ifdef HAVE_SIG_INFO
+ MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
+#endif
+ MONO_SIG_HANDLER_GET_CONTEXT;
#if defined(MONO_ARCH_SOFT_DEBUG_SUPPORTED) && defined(HAVE_SIG_INFO)
if (mono_arch_is_single_step_event (info, ctx)) {
/* The thread might no be registered with the runtime */
if (!mono_domain_get () || !jit_tls) {
- if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS))
+ if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
mono_handle_native_sigsegv (SIGSEGV, ctx);
if (mono_do_crash_chaining) {
- mono_chain_signal (SIG_HANDLER_PARAMS);
+ mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
return;
}
}
if (fault_addr == NULL) {
MonoContext mctx;
- mono_arch_sigctx_to_monoctx (ctx, &mctx);
+ mono_sigctx_to_monoctx (ctx, &mctx);
fault_addr = MONO_CONTEXT_GET_SP (&mctx);
}
g_assert_not_reached ();
} else {
/* The original handler might not like that it is executed on an altstack... */
- if (!ji && mono_chain_signal (SIG_HANDLER_PARAMS))
+ if (!ji && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
mono_arch_handle_altstack_exception (ctx, info->si_addr, FALSE);
#else
if (!ji) {
- if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS))
+ if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
mono_handle_native_sigsegv (SIGSEGV, ctx);
if (mono_do_crash_chaining) {
- mono_chain_signal (SIG_HANDLER_PARAMS);
+ mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
return;
}
}
#endif
}
-SIG_HANDLER_FUNC (, mono_sigint_signal_handler)
+MONO_SIG_HANDLER_FUNC (, mono_sigint_signal_handler)
{
MonoException *exc;
- GET_CONTEXT;
+ MONO_SIG_HANDLER_GET_CONTEXT;
exc = mono_get_exception_execution_engine ("Interrupted (SIGINT).");
else if (!strcmp (arg, "explicit-null-checks"))
debug_options.explicit_null_checks = TRUE;
else if (!strcmp (arg, "gen-seq-points"))
- debug_options.gen_seq_points = TRUE;
+ debug_options.gen_seq_points_debug_data = TRUE;
else if (!strcmp (arg, "init-stacks"))
debug_options.init_stacks = TRUE;
else if (!strcmp (arg, "casts"))
static gpointer
mini_create_ftnptr (MonoDomain *domain, gpointer addr)
{
-#if !defined(__ia64__) && !defined(__ppc64__) && !defined(__powerpc64__)
+#if !defined(__ia64__) && (!defined(__ppc64__) && !defined(__powerpc64__) || _CALL_ELF == 2)
return addr;
#else
-
gpointer* desc = NULL;
if ((desc = g_hash_table_lookup (domain->ftnptrs_hash, addr)))
static gpointer
mini_get_addr_from_ftnptr (gpointer descr)
{
-#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__)
+#if defined(__ia64__) || ((defined(__ppc64__) || defined(__powerpc64__)) && _CALL_ELF != 2)
return *(gpointer*)descr;
#else
return descr;
mono_counters_register ("Allocated vars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocate_var);
mono_counters_register ("Code reallocs", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.code_reallocs);
mono_counters_register ("Allocated code size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocated_code_size);
+ mono_counters_register ("Allocated seq points size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocated_seq_points_size);
mono_counters_register ("Inlineable methods", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.inlineable_methods);
mono_counters_register ("Inlined methods", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.inlined_methods);
mono_counters_register ("Regvars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.regvars);
}
static void runtime_invoke_info_free (gpointer value);
-static void seq_point_info_free (gpointer value);
static gint
class_method_pair_equal (gconstpointer ka, gconstpointer kb)
g_free (info);
}
-static void seq_point_info_free (gpointer value)
-{
- int i = 0;
- MonoSeqPointInfo* info = (MonoSeqPointInfo*)value;
-
- for (i = 0; i < info->len; ++i) {
- SeqPoint *sp = &info->seq_points [i];
- g_free (sp->next);
- }
-
- g_free (info);
-}
-
static void
mini_free_jit_domain_info (MonoDomain *domain)
{
domain->runtime_info = NULL;
}
+#ifdef ENABLE_LLVM
+static gboolean
+llvm_init_inner (void)
+{
+ if (!mono_llvm_load (NULL))
+ return FALSE;
+
+ mono_llvm_init ();
+ return TRUE;
+}
+#endif
+
+/*
+ * mini_llvm_init:
+ *
+ * Load and initialize LLVM support.
+ * Return TRUE on success.
+ */
+gboolean
+mini_llvm_init (void)
+{
+#ifdef ENABLE_LLVM
+ static gboolean llvm_inited;
+ static gboolean init_result;
+
+ mono_loader_lock_if_inited ();
+ if (!llvm_inited) {
+ init_result = llvm_init_inner ();
+ llvm_inited = TRUE;
+ }
+ mono_loader_unlock_if_inited ();
+ return init_result;
+#else
+ return FALSE;
+#endif
+}
+
MonoDomain *
mini_init (const char *filename, const char *runtime_version)
{
mono_threads_install_cleanup (mini_thread_cleanup);
#ifdef MONO_ARCH_HAVE_NOTIFY_PENDING_EXC
- // This is experimental code so provide an env var to switch it off
- if (g_getenv ("MONO_DISABLE_PENDING_EXCEPTIONS")) {
- printf ("MONO_DISABLE_PENDING_EXCEPTIONS env var set.\n");
- } else {
- check_for_pending_exc = FALSE;
- mono_threads_install_notify_pending_exc (mono_arch_notify_pending_exc);
- }
+ check_for_pending_exc = FALSE;
+ mono_threads_install_notify_pending_exc ((MonoThreadNotifyPendingExcFunc)mono_arch_notify_pending_exc);
#endif
#define JIT_TRAMPOLINES_WORK
method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL);
if (method->flags & METHOD_ATTRIBUTE_ABSTRACT)
continue;
+ if (method->is_generic || method->klass->generic_container)
+ continue;
count++;
if (mini_verbose > 1) {