switch (type->type) {
case MONO_TYPE_I1:
case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
return OP_STOREI1_MEMBASE_REG;
case MONO_TYPE_I2:
case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
return OP_STOREI2_MEMBASE_REG;
case MONO_TYPE_I4:
case MONO_TYPE_U4:
case MONO_TYPE_I1:
return OP_LOADI1_MEMBASE;
case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
return OP_LOADU1_MEMBASE;
case MONO_TYPE_I2:
return OP_LOADI2_MEMBASE;
case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
return OP_LOADU2_MEMBASE;
case MONO_TYPE_I4:
return OP_LOADI4_MEMBASE;
if (cfg->opt & MONO_OPT_PEEPHOLE)
mono_arch_peephole_pass_2 (cfg, bb);
- if (cfg->gen_seq_points && !cfg->gen_seq_points_debug_data)
+ if (cfg->gen_seq_points && !cfg->gen_sdb_seq_points)
bb_deduplicate_op_il_seq_points (cfg, bb);
}
#endif
/* Allocate the code into a separate memory pool so it can be freed */
cfg->dynamic_info = g_new0 (MonoJitDynamicMethodInfo, 1);
- cfg->dynamic_info->code_mp = mono_code_manager_new_dynamic ();
+ cfg->dynamic_info->code_mp = mono_code_manager_new_dynamic (cfg->thunk_area);
mono_domain_lock (cfg->domain);
mono_dynamic_code_hash_insert (cfg->domain, cfg->method, cfg->dynamic_info);
mono_domain_unlock (cfg->domain);
ei->flags = ec->flags;
+ if (G_UNLIKELY (cfg->verbose_level >= 4))
+ printf ("IL clause: try 0x%x-0x%x handler 0x%x-0x%x filter 0x%x\n", ec->try_offset, ec->try_offset + ec->try_len, ec->handler_offset, ec->handler_offset + ec->handler_len, ec->flags == MONO_EXCEPTION_CLAUSE_FILTER ? ec->data.filter_offset : 0);
+
/*
* The spvars are needed by mono_arch_install_handler_block_guard ().
*/
}
#endif
-static gboolean
-is_gsharedvt_type (MonoType *t)
-{
- return (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE;
-}
-
/* Return whenever METHOD is a gsharedvt method */
static gboolean
is_gsharedvt_method (MonoMethod *method)
inst = context->class_inst;
if (inst) {
for (i = 0; i < inst->type_argc; ++i)
- if (is_gsharedvt_type (inst->type_argv [i]))
+ if (mini_is_gsharedvt_gparam (inst->type_argv [i]))
return TRUE;
}
inst = context->method_inst;
if (inst) {
for (i = 0; i < inst->type_argc; ++i)
- if (is_gsharedvt_type (inst->type_argv [i]))
+ if (mini_is_gsharedvt_gparam (inst->type_argv [i]))
return TRUE;
}
return FALSE;
}
#ifndef DISABLE_JIT
+
+#if defined(__native_client_codegen__) || USE_COOP_GC
+
+static void
+mono_create_gc_safepoint (MonoCompile *cfg, MonoBasicBlock *bblock)
+{
+ MonoInst *poll_addr, *ins;
+ if (cfg->verbose_level)
+ printf ("ADDING SAFE POINT TO BB %d\n", bblock->block_num);
+
+#if defined(__native_client_codegen__)
+ NEW_AOTCONST (cfg, poll_addr, MONO_PATCH_INFO_GC_SAFE_POINT_FLAG, (gpointer)&__nacl_thread_suspension_needed);
+#else
+ NEW_AOTCONST (cfg, poll_addr, MONO_PATCH_INFO_GC_SAFE_POINT_FLAG, (gpointer)&mono_polling_required);
+#endif
+
+ MONO_INST_NEW (cfg, ins, OP_GC_SAFE_POINT);
+ ins->sreg1 = poll_addr->dreg;
+
+ if (bblock->flags & BB_EXCEPTION_HANDLER) {
+ MonoInst *eh_op = bblock->code;
+
+ // we only skip the ops that start EH blocks.
+ if (eh_op && eh_op->opcode != OP_START_HANDLER && eh_op->opcode != OP_GET_EX_OBJ)
+ eh_op = NULL;
+
+ mono_bblock_insert_after_ins (bblock, eh_op, poll_addr);
+ mono_bblock_insert_after_ins (bblock, poll_addr, ins);
+ } else if (bblock == cfg->bb_entry) {
+ mono_bblock_insert_after_ins (bblock, bblock->last_ins, poll_addr);
+ mono_bblock_insert_after_ins (bblock, poll_addr, ins);
+
+ } else {
+ mono_bblock_insert_before_ins (bblock, NULL, poll_addr);
+ mono_bblock_insert_after_ins (bblock, poll_addr, ins);
+ }
+}
+
+/*
+This code inserts safepoints into managed code at important code paths.
+Those are:
+
+-the first basic block
+-landing BB for exception handlers
+-loop body starts.
+
+*/
+static void
+mono_insert_safepoints (MonoCompile *cfg)
+{
+ MonoBasicBlock *bb;
+
+ if (cfg->verbose_level)
+ printf ("INSERTING SAFEPOINTS\n");
+
+ for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+ if (bb->loop_body_start || bb == cfg->bb_entry || bb->flags & BB_EXCEPTION_HANDLER)
+ mono_create_gc_safepoint (cfg, bb);
+ }
+}
+
+#else
+
+static void
+mono_insert_safepoints (MonoCompile *cfg)
+{
+}
+
+#endif
+
/*
* mini_method_compile:
* @method: the method to compile
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;
+ gboolean disable_direct_icalls = (flags & JIT_FLAG_NO_DIRECT_ICALLS) ? 1 : 0;
+ gboolean gsharedvt_method = FALSE;
#ifdef ENABLE_LLVM
gboolean llvm = (flags & JIT_FLAG_LLVM) ? 1 : 0;
#endif
if (MONO_METHOD_COMPILE_BEGIN_ENABLED ())
MONO_PROBE_METHOD_COMPILE_BEGIN (method);
+ /*
+ * In AOT mode, method can be the following:
+ * - the generic method definition. In this case, we are compiling the fully shared
+ * version of the method, i.e. the version where all the type parameters are
+ * reference types.
+ * - a gsharedvt method.
+ * - a method inflated with type parameters. This is for partial sharing.
+ * - a method inflated with concrete types.
+ */
if (compile_aot)
- /*
- * We might get passed the original generic method definition or
- * instances with type parameters.
- * FIXME: Remove the method->klass->generic_class limitation.
- */
try_generic_shared = mono_class_generic_sharing_enabled (method->klass) &&
(opts & MONO_OPT_GSHARED) && ((method->is_generic || method->klass->generic_container) || (!method->klass->generic_class && mono_method_is_generic_sharable_full (method, TRUE, FALSE, FALSE)));
else
try_generic_shared = FALSE;
}
- if (is_gsharedvt_method (method) || (compile_aot && is_open_method (method))) {
+ gsharedvt_method = is_gsharedvt_method (method);
+ if (gsharedvt_method || (compile_aot && is_open_method (method))) {
/* We are AOTing a gshared method directly */
method_is_gshared = TRUE;
g_assert (compile_aot);
cfg->full_aot = full_aot;
cfg->skip_visibility = method->skip_visibility;
cfg->orig_method = method;
- cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_seq_points_debug_data;
- cfg->gen_seq_points_debug_data = debug_options.gen_seq_points_debug_data;
+ cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_sdb_seq_points;
+ cfg->gen_sdb_seq_points = debug_options.gen_sdb_seq_points;
+
+#ifdef PLATFORM_ANDROID
+ if (cfg->method->wrapper_type != MONO_WRAPPER_NONE) {
+ /* FIXME: Why is this needed */
+ cfg->gen_seq_points = FALSE;
+ cfg->gen_sdb_seq_points = FALSE;
+ }
+#endif
+ /* coop / nacl requires loop detection to happen */
+#if defined(__native_client_codegen__) || defined(USE_COOP_GC)
+ cfg->opt |= MONO_OPT_LOOP;
+#endif
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;
+ cfg->disable_direct_icalls = disable_direct_icalls;
if (try_generic_shared)
cfg->generic_sharing_context = (MonoGenericSharingContext*)&cfg->gsctx;
cfg->compile_llvm = try_llvm;
return cfg;
}
- if (cfg->generic_sharing_context && (mini_is_gsharedvt_sharable_method (method) || method_is_gshared)) {
+ if (cfg->generic_sharing_context && (gsharedvt_method || mini_is_gsharedvt_sharable_method (method))) {
MonoMethodInflated *inflated;
MonoGenericContext *context;
- if (method_is_gshared) {
+ if (gsharedvt_method) {
g_assert (method->is_inflated);
inflated = (MonoMethodInflated*)method;
context = &inflated->context;
g_free (method_name);
}
- if (cfg->opt & (MONO_OPT_ABCREM | MONO_OPT_SSAPRE))
+ if (cfg->opt & MONO_OPT_ABCREM)
cfg->opt |= MONO_OPT_SSA;
/*
*/
mono_compile_create_vars (cfg);
- /* 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, 0, FALSE);
if (i < 0) {
if (!COMPILE_LLVM (cfg))
mono_if_conversion (cfg);
- if ((cfg->opt & MONO_OPT_SSAPRE) || cfg->globalra)
+ if (cfg->globalra)
mono_remove_critical_edges (cfg);
/* Depth-first ordering on basic blocks */
mono_compute_natural_loops (cfg);
}
+ mono_insert_safepoints (cfg);
+
/* after method_to_ir */
if (parts == 1) {
if (MONO_METHOD_COMPILE_END_ENABLED ())
if (cfg->comp_done & MONO_COMP_SSA && !COMPILE_LLVM (cfg)) {
//mono_ssa_strength_reduction (cfg);
- if (cfg->opt & MONO_OPT_SSAPRE) {
- mono_perform_ssapre (cfg);
- //mono_local_cprop (cfg);
- }
-
if (cfg->opt & MONO_OPT_DEADCE)
mono_ssa_deadce (cfg);