#include <math.h>
#include <sys/time.h>
-#ifdef sun // Solaris x86
-#include <sys/types.h>
-#include <sys/ucontext.h>
-#endif
-
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#define MONO_IS_COND_BRANCH_OP(ins) (((ins)->opcode >= CEE_BEQ && (ins)->opcode <= CEE_BLT_UN) || ((ins)->opcode >= OP_LBEQ && (ins)->opcode <= OP_LBLT_UN) || ((ins)->opcode >= OP_FBEQ && (ins)->opcode <= OP_FBLT_UN) || ((ins)->opcode >= OP_IBEQ && (ins)->opcode <= OP_IBLT_UN))
#define MONO_IS_COND_BRANCH_NOFP(ins) (MONO_IS_COND_BRANCH_OP(ins) && (ins)->inst_left->inst_left->type != STACK_R8)
+#define MONO_IS_BRANCH_OP(ins) (MONO_IS_COND_BRANCH_OP(ins) || ((ins)->opcode == CEE_BR) || ((ins)->opcode == OP_BR_REG) || ((ins)->opcode == CEE_SWITCH))
+
#define MONO_CHECK_THIS(ins) (mono_method_signature (cfg->method)->hasthis && (ins)->ssa_op == MONO_SSA_LOAD && (ins)->inst_left->inst_c0 == 0)
static void setup_stat_profiler (void);
if (!(cfg->opt & MONO_OPT_SHARED)) {
vtable = mono_class_vtable (cfg->domain, method->klass);
if (method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
- if (cfg->run_cctors)
+ if (cfg->run_cctors) {
+ /* This makes so that inline cannot trigger */
+ /* .cctors: too many apps depend on them */
+ /* running with a specific order... */
+ if (! vtable->initialized)
+ return FALSE;
mono_runtime_class_init (vtable);
+ }
}
else if (!vtable->initialized && mono_class_needs_cctor_run (method->klass, NULL))
return FALSE;
sp++;
}
}
-#define MONO_INLINE_CALLED_LIMITED_METHODS 1
-#define MONO_INLINE_CALLER_LIMITED_METHODS 1
+#define MONO_INLINE_CALLED_LIMITED_METHODS 0
+#define MONO_INLINE_CALLER_LIMITED_METHODS 0
#if (MONO_INLINE_CALLED_LIMITED_METHODS)
static char*
return klass;
}
+/*
+ * Returns TRUE if the JIT should abort inlining because "callee"
+ * is influenced by security attributes.
+ */
static
-void check_linkdemand (MonoCompile *cfg, MonoMethod *caller, MonoMethod *callee, MonoBasicBlock *bblock, unsigned char *ip)
+gboolean check_linkdemand (MonoCompile *cfg, MonoMethod *caller, MonoMethod *callee, MonoBasicBlock *bblock, unsigned char *ip)
{
- guint32 result = mono_declsec_linkdemand (cfg->domain, caller, callee);
+ guint32 result;
+
+ if ((cfg->method != caller) && mono_method_has_declsec (callee)) {
+ return TRUE;
+ }
+
+ result = mono_declsec_linkdemand (cfg->domain, caller, callee);
if (result == MONO_JIT_SECURITY_OK)
- return;
+ return FALSE;
if (result == MONO_JIT_LINKDEMAND_ECMA) {
/* Generate code to throw a SecurityException before the actual call/link */
cfg->exception_type = MONO_EXCEPTION_SECURITY_LINKDEMAND;
cfg->exception_data = result;
}
+
+ return FALSE;
}
static gboolean
dont_verify |= method->wrapper_type == MONO_WRAPPER_XDOMAIN_INVOKE;
dont_verify |= method->wrapper_type == MONO_WRAPPER_XDOMAIN_DISPATCH;
dont_verify |= method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE; /* bug #77896 */
+ dont_verify |= method->wrapper_type == MONO_WRAPPER_COMINTEROP;
- /* still some type unsefety issues in marshal wrappers... (unknown is PtrToStructure) */
+ /* still some type unsafety issues in marshal wrappers... (unknown is PtrToStructure) */
dont_verify_stloc = method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE;
dont_verify_stloc |= method->wrapper_type == MONO_WRAPPER_UNKNOWN;
dont_verify_stloc |= method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED;
goto load_error;
if (mono_use_security_manager) {
- check_linkdemand (cfg, method, cmethod, bblock, ip);
+ if (check_linkdemand (cfg, method, cmethod, bblock, ip))
+ INLINE_FAILURE;
}
ins->inst_p0 = cmethod;
n = fsig->param_count + fsig->hasthis;
if (mono_use_security_manager) {
- check_linkdemand (cfg, method, cmethod, bblock, ip);
+ if (check_linkdemand (cfg, method, cmethod, bblock, ip))
+ INLINE_FAILURE;
}
if (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL &&
}
ip += 5;
+ ins_flag = 0;
break;
}
if ((ins_flag & MONO_INST_TAILCALL) && cmethod && (*ip == CEE_CALL) &&
(mono_metadata_signature_equal (mono_method_signature (method), mono_method_signature (cmethod)))) {
int i;
+
/* Prevent inlining of methods with tail calls (the call stack would be altered) */
INLINE_FAILURE;
/* FIXME: This assumes the two methods has the same number and type of arguments */
}
ip += 5;
+ ins_flag = 0;
break;
}
bblock = ebblock;
inline_costs += costs;
+ ins_flag = 0;
break;
}
}
ip += 6;
else
ip += 5;
-
+ ins_flag = 0;
break;
}
}
}
ip += 5;
+ ins_flag = 0;
break;
}
case CEE_RET:
goto load_error;
if (mono_use_security_manager) {
- check_linkdemand (cfg, method, cmethod, bblock, ip);
+ if (check_linkdemand (cfg, method, cmethod, bblock, ip))
+ INLINE_FAILURE;
}
n = fsig->param_count;
g_print ("class %s.%s needs init call for %s\n", klass->name_space, klass->name, field->name);
class_inits = g_slist_prepend (class_inits, vtable);
} else {
- if (cfg->run_cctors)
+ if (cfg->run_cctors) {
+ /* This makes so that inline cannot trigger */
+ /* .cctors: too many apps depend on them */
+ /* running with a specific order... */
+ if (! vtable->initialized)
+ INLINE_FAILURE;
mono_runtime_class_init (vtable);
+ }
}
addr = (char*)vtable->data + field->offset;
mono_class_init (cmethod->klass);
if (mono_use_security_manager) {
- check_linkdemand (cfg, method, cmethod, bblock, ip);
+ if (check_linkdemand (cfg, method, cmethod, bblock, ip))
+ INLINE_FAILURE;
}
handle_loaded_temps (cfg, bblock, stack_start, sp);
mono_class_init (cmethod->klass);
if (mono_use_security_manager) {
- check_linkdemand (cfg, method, cmethod, bblock, ip);
+ if (check_linkdemand (cfg, method, cmethod, bblock, ip))
+ INLINE_FAILURE;
}
handle_loaded_temps (cfg, bblock, stack_start, sp);
}
}
+/**
+ * mono_patch_info_dup_mp:
+ *
+ * Make a copy of PATCH_INFO, allocating memory from the mempool MP.
+ */
+MonoJumpInfo*
+mono_patch_info_dup_mp (MonoMemPool *mp, MonoJumpInfo *patch_info)
+{
+ MonoJumpInfo *res = mono_mempool_alloc (mp, sizeof (MonoJumpInfo));
+ memcpy (res, patch_info, sizeof (MonoJumpInfo));
+
+ switch (patch_info->type) {
+ case MONO_PATCH_INFO_LDSTR:
+ case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
+ case MONO_PATCH_INFO_LDTOKEN:
+ case MONO_PATCH_INFO_DECLSEC:
+ res->data.token = mono_mempool_alloc (mp, sizeof (MonoJumpInfoToken));
+ memcpy (res->data.token, patch_info->data.token, sizeof (MonoJumpInfoToken));
+ break;
+ case MONO_PATCH_INFO_SWITCH:
+ res->data.table = mono_mempool_alloc (mp, sizeof (MonoJumpInfoBBTable));
+ memcpy (res->data.table, patch_info->data.table, sizeof (MonoJumpInfoBBTable));
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
gpointer
mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors)
{
if ((previous_bb == cfg->bb_entry) && (bb->next_bb != target_bb)) {
return FALSE;
}
+
+ /*
+ * Do not touch BBs following a try block as the code in
+ * mini_method_compile needs them to compute the length of the try block.
+ */
+ if (MONO_BBLOCK_IS_IN_REGION (previous_bb, MONO_REGION_TRY))
+ return FALSE;
/* Check that there is a target BB, and that bb is not an empty loop (Bug 75061) */
if ((target_bb != NULL) && (target_bb != bb)) {
replace_basic_block (bb, bbn, bb);
+ /* Nullify branch at the end of bb */
+ if (bb->last_ins && MONO_IS_BRANCH_OP (bb->last_ins)) {
+ bb->last_ins->opcode = CEE_NOP;
+ }
+
if (bb->last_ins) {
if (bbn->code) {
bb->last_ins->next = bbn->code;
if (parts == 3)
return cfg;
+ if (cfg->verbose_level > 4) {
+ printf ("BEFORE DECOMPSE START\n");
+ mono_print_code (cfg);
+ printf ("BEFORE DECOMPSE END\n");
+ }
+
decompose_pass (cfg);
if (cfg->got_var) {
MonoMethod *nm;
MonoMethodPInvoke* piinfo = (MonoMethodPInvoke *) method;
- if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE && !MONO_CLASS_IS_IMPORT(method->klass))
g_error ("Method '%s' in assembly '%s' contains native code and mono can't run it. The assembly was probably created by Managed C++.\n", mono_method_full_name (method, TRUE), method->klass->image->name);
if (!piinfo->addr) {
#ifdef __sparc
#define GET_CONTEXT \
void *ctx = context;
-#elif defined(sun) // Solaris x86
-#define GET_CONTEXT \
- ucontext_t *uctx = context; \
- struct sigcontext *ctx = (struct sigcontext *)&(uctx->uc_mcontext);
#elif defined (MONO_ARCH_USE_SIGACTION)
#define GET_CONTEXT \
void *ctx = context;
mono_trace_cleanup ();
mono_counters_dump (-1, stdout);
+
+ TlsFree(mono_jit_tls_id);
+
+ DeleteCriticalSection (&jit_mutex);
+
+ DeleteCriticalSection (&mono_delegate_section);
}
void