/*
* This flag controls whenever the runtime uses LLVM compiled code.
* Enabling this causes different/slower code paths to be used, which is why it
- * defaults to FALSE if ENABLE_LLVM is not defined, i.e. the runtime is only capable of
- * running AOT code compiled by LLVM.
+ * defaults to FALSE.
* Changes when this flag is set include:
* - a per method vtable trampoline is used to handle virtual calls, instead of only
* one trampoline.
{
return mono_jump_info_token_new2 (mp, image, token, NULL);
}
+
+/*
+ * mono_tramp_info_create:
+ *
+ * Create a MonoTrampInfo structure from the arguments. This function assumes ownership
+ * of NAME, JI, and UNWIND_OPS.
+ */
+MonoTrampInfo*
+mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops)
+{
+ MonoTrampInfo *info = g_new0 (MonoTrampInfo, 1);
+
+ info->name = (char*)name;
+ info->code = code;
+ info->code_size = code_size;
+ info->ji = ji;
+ info->unwind_ops = unwind_ops;
+
+ return info;
+}
+
+void
+mono_tramp_info_free (MonoTrampInfo *info)
+{
+ g_free (info->name);
+
+ // FIXME: ji + unwind_ops
+}
#define MONO_INIT_VARINFO(vi,id) do { \
(vi)->range.first_use.pos.bid = 0xffff; \
mono_create_tls_get (MonoCompile *cfg, int offset)
{
#ifdef MONO_ARCH_HAVE_TLS_GET
- MonoInst* ins;
-
- if (offset == -1)
- return NULL;
-
- MONO_INST_NEW (cfg, ins, OP_TLS_GET);
- ins->dreg = mono_alloc_preg (cfg);
- ins->inst_offset = offset;
- return ins;
-#else
- return NULL;
+ if (MONO_ARCH_HAVE_TLS_GET) {
+ MonoInst* ins;
+
+ if (offset == -1)
+ return NULL;
+
+ MONO_INST_NEW (cfg, ins, OP_TLS_GET);
+ ins->dreg = mono_alloc_preg (cfg);
+ ins->inst_offset = offset;
+ return ins;
+ }
#endif
+ return NULL;
}
MonoInst*
table->num_holes = (guint16)num_holes;
i = 0;
for (tmp = cfg->try_block_holes; tmp; tmp = tmp->next) {
+ guint32 start_bb_offset;
MonoTryBlockHoleJitInfo *hole;
TryBlockHole *hole_data = tmp->data;
MonoExceptionClause *ec = hole_data->clause;
if (clause_last_bb->native_offset == hole_end)
continue;
+ start_bb_offset = hole_data->start_offset - hole_data->basic_block->native_offset;
hole = &table->holes [i++];
hole->clause = hole_data->clause - &header->clauses [0];
hole->offset = (guint32)hole_data->start_offset;
- hole->length = (guint16)(hole_data->basic_block->native_length - hole_data->start_offset);
- }
- g_assert (i == num_holes);
- }
+ hole->length = (guint16)(hole_data->basic_block->native_length - start_bb_offset);
- if (G_UNLIKELY (header->num_clauses && cfg->verbose_level >= 4)) {
- GSList *tmp;
- int i;
- printf ("\nException Handling Data\n");
- for (i = 0; i < header->num_clauses; i++) {
- MonoExceptionClause *ec = &header->clauses [i];
- int try_start = cfg->cil_offset_to_bb [ec->try_offset]->native_offset;
- int try_end = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len]->native_offset;
- int handler_start = cfg->cil_offset_to_bb [ec->handler_offset]->native_offset;
- int handler_end;
- if (ec->handler_offset + ec->handler_len < header->code_size)
- handler_end = cfg->cil_offset_to_bb [ec->handler_offset + ec->handler_len]->native_offset;
- else
- handler_end = cfg->epilog_begin;
-
- printf ("EH clause %d flags %x try IL %x-%x NATIVE %x-%x handler IL %x-%x NATIVE %x-%x\n",
- i, ec->flags,
- ec->try_offset, ec->try_offset + ec->try_len, try_start, try_end,
- ec->handler_offset, ec->handler_offset + ec->handler_len, handler_start, handler_end);
- }
- for (tmp = cfg->try_block_holes; tmp; tmp = tmp->next) {
- TryBlockHole *hole = tmp->data;
- int block = hole->clause - &header->clauses [0];
- printf ("try block hole at eh clause %d range %x-%x\n",
- block, hole->start_offset, hole->basic_block->native_offset + hole->basic_block->native_length);
+ if (G_UNLIKELY (cfg->verbose_level >= 4))
+ printf ("\tTry block hole at eh clause %d offset %x length %x\n", hole->clause, hole->offset, hole->length);
}
+ g_assert (i == num_holes);
}
if (COMPILE_LLVM (cfg)) {
gpointer hole_end = cfg->native_code + (hole->basic_block->native_offset + hole->basic_block->native_length);
if (hole->clause == ec && hole_end == ei->try_end) {
if (G_UNLIKELY (cfg->verbose_level >= 4))
- printf ("\tShortening try block %d from %p to %p\n", i, ei->try_end, cfg->native_code + hole->start_offset);
+ printf ("\tShortening try block %d from %x to %x\n", i, (int)((guint8*)ei->try_end - cfg->native_code), hole->start_offset);
+
ei->try_end = cfg->native_code + hole->start_offset;
break;
}
}
+
+ if (ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
+ int end_offset;
+ if (ec->handler_offset + ec->handler_len < header->code_size) {
+ tblock = cfg->cil_offset_to_bb [ec->handler_offset + ec->handler_len];
+ g_assert (tblock);
+ end_offset = tblock->native_offset;
+ } else {
+ end_offset = cfg->epilog_begin;
+ }
+ ei->data.handler_end = cfg->native_code + end_offset;
+ }
}
if (G_UNLIKELY (cfg->verbose_level >= 4)) {
for (i = 0; i < jinfo->num_clauses; i++) {
MonoJitExceptionInfo *ei = &jinfo->clauses [i];
- printf ("JitInfo EH clause %d flags %x try %p-%p handler %p\n", i, ei->flags, ei->try_start, ei->try_end, ei->handler_start);
+ int start = (guint8*)ei->try_start - cfg->native_code;
+ int end = (guint8*)ei->try_end - cfg->native_code;
+ int handler = (guint8*)ei->handler_start - cfg->native_code;
+
+ printf ("JitInfo EH clause %d flags %x try %x-%x handler %x\n", i, ei->flags, start, end, handler);
}
}
return jinfo;
}
+#endif
/*
* mini_get_shared_method:
return res;
}
+#ifndef DISABLE_JIT
/*
* mini_method_compile:
* @method: the method to compile
mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, gboolean compile_aot, int parts)
{
MonoMethodHeader *header;
+ MonoMethodSignature *sig;
+ MonoError err;
guint8 *ip;
MonoCompile *cfg;
int dfn, i, code_size_ratio;
}
}
+ mono_error_init (&err);
+ sig = mono_method_signature_checked (cfg->method, &err);
+ if (!sig) {
+ cfg->exception_type = MONO_EXCEPTION_TYPE_LOAD;
+ cfg->exception_message = g_strdup (mono_error_get_message (&err));
+ mono_error_cleanup (&err);
+ if (MONO_PROBE_METHOD_COMPILE_END_ENABLED ())
+ MONO_PROBE_METHOD_COMPILE_END (method, FALSE);
+ return cfg;
+ }
+
header = cfg->header;
if (!header) {
MonoLoaderError *error;
return cfg;
}
- if (FALSE && header->clauses) {
- /*
- * Cannot be enabled until LLVM supports implicit exceptions, or we use
- * explicit checks, or we disable this for methods which might throw implicit
- * exceptions inside clauses.
+ if (header->clauses) {
+ /*
+ * FIXME: LLLVM 2.6/SVN no longer seems to generate correct exception info
+ * for JITted code.
*/
cfg->exception_message = g_strdup ("clauses");
cfg->disable_llvm = TRUE;
mono_decompose_array_access_opts (cfg);
if (cfg->got_var) {
+#ifndef MONO_ARCH_GOT_REG
GList *regs;
+#endif
+ int got_reg;
g_assert (cfg->got_var_allocated);
* branches problem. Testcase: mcs crash in
* System.MonoCustomAttrs:GetCustomAttributes.
*/
+#ifdef MONO_ARCH_GOT_REG
+ got_reg = MONO_ARCH_GOT_REG;
+#else
regs = mono_arch_get_global_int_regs (cfg);
g_assert (regs);
+ got_reg = GPOINTER_TO_INT (regs->data);
+ g_list_free (regs);
+#endif
cfg->got_var->opcode = OP_REGVAR;
- cfg->got_var->dreg = GPOINTER_TO_INT (regs->data);
+ cfg->got_var->dreg = got_reg;
cfg->used_int_regs |= 1LL << cfg->got_var->dreg;
-
- g_list_free (regs);
}
/*
}
if ((cfg->opt & MONO_OPT_LINEARS) && !cfg->globalra) {
- GList *vars, *regs;
+ GList *vars, *regs, *l;
/* fixme: maybe we can avoid to compute livenesss here if already computed ? */
cfg->comp_done &= ~MONO_COMP_LIVENESS;
if ((vars = mono_arch_get_allocatable_int_vars (cfg))) {
regs = mono_arch_get_global_int_regs (cfg);
- if (cfg->got_var)
- regs = g_list_delete_link (regs, regs);
+ /* Remove the reg reserved for holding the GOT address */
+ if (cfg->got_var) {
+ for (l = regs; l; l = l->next) {
+ if (GPOINTER_TO_UINT (l->data) == cfg->got_var->dreg) {
+ regs = g_list_delete_link (regs, l);
+ break;
+ }
+ }
+ }
mono_linear_scan (cfg, vars, regs, &cfg->used_int_regs);
}
}
}
#endif
+#ifndef DISABLE_JIT
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
MonoMethod *nm;
}
return NULL;
}
+#endif
if (mono_aot_only) {
char *fullname = mono_method_full_name (method, TRUE);
mono_destroy_compile (cfg);
+#ifndef DISABLE_JIT
if (domain_jit_info (target_domain)->jump_target_hash) {
MonoJumpInfo patch_info;
GSList *list, *tmp;
}
mono_emit_jit_map (jinfo);
+#endif
mono_domain_unlock (target_domain);
mono_loader_unlock ();
}
if (prof_options & MONO_PROFILE_JIT_COMPILATION) {
- if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
- /* The profiler doesn't know about wrappers, so pass the original icall method */
- mono_profiler_method_end_jit (mono_marshal_method_from_wrapper (method), jinfo, MONO_PROFILE_OK);
- else
+ if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ if (mono_marshal_method_from_wrapper (method)) {
+ /* Native func wrappers have no method */
+ /* The profiler doesn't know about wrappers, so pass the original icall method */
+ mono_profiler_method_end_jit (mono_marshal_method_from_wrapper (method), jinfo, MONO_PROFILE_OK);
+ }
+ } else {
mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
+ }
}
mono_runtime_class_init (vtable);
#endif
#ifdef MONO_ARCH_HAVE_TLS_GET
- mono_runtime_set_has_tls_get (TRUE);
+ mono_runtime_set_has_tls_get (MONO_ARCH_HAVE_TLS_GET);
#else
mono_runtime_set_has_tls_get (FALSE);
#endif
if (!g_thread_supported ())
g_thread_init (NULL);
- mono_gc_base_init ();
-
mono_jit_tls_id = TlsAlloc ();
setup_jit_tls_data ((gpointer)-1, mono_thread_abort);