* FIXME: The metadata calls might not be signal safe.
*/
int
-mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
{
int len, k, args_size = 0;
int size, pad;
cinfo = (CallInfo*)g_newa (guint8*, len);
memset (cinfo, 0, len);
- cinfo = get_call_info_internal (NULL, cinfo, csig);
+ cinfo = get_call_info_internal (gsctx, cinfo, csig);
arg_info [0].offset = offset;
void
mono_arch_cleanup (void)
{
+ if (ss_trigger_page)
+ mono_vfree (ss_trigger_page, mono_pagesize ());
+ if (bp_trigger_page)
+ mono_vfree (bp_trigger_page, mono_pagesize ());
DeleteCriticalSection (&mini_arch_mutex);
}
* This function returns the optimizations supported on this cpu.
*/
guint32
-mono_arch_cpu_optimizazions (guint32 *exclude_mask)
+mono_arch_cpu_optimizations (guint32 *exclude_mask)
{
#if !defined(__native_client__)
int eax, ebx, ecx, edx;
if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig->ret)) {
cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
}
+
+ cfg->arch_eh_jit_info = 1;
}
/*
emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo)
{
MonoMethodSignature *tmp_sig;
-
- /* FIXME: Add support for signature tokens to AOT */
- cfg->disable_aot = TRUE;
+ int sig_reg;
/*
* mono_ArgIterator_Setup assumes the signature cookie is
tmp_sig->sentinelpos = 0;
memcpy (tmp_sig->params, call->signature->params + call->signature->sentinelpos, tmp_sig->param_count * sizeof (MonoType*));
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig);
+ if (cfg->compile_aot) {
+ sig_reg = mono_alloc_ireg (cfg);
+ MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig);
+ MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg);
+ } else {
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig);
+ }
}
#ifdef ENABLE_LLVM
/* Arguments are pushed in the reverse order */
for (i = n - 1; i >= 0; i --) {
ArgInfo *ainfo = cinfo->args + i;
- MonoType *t;
+ MonoType *orig_type, *t;
int argsize;
if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 1 && i == 0) {
t = sig->params [i - sig->hasthis];
else
t = &mono_defaults.int_class->byval_arg;
+ orig_type = t;
t = mini_type_get_underlying_type (cfg->generic_sharing_context, t);
MONO_INST_NEW (cfg, arg, OP_X86_PUSH);
MONO_ADD_INS (cfg->cbb, arg);
sp_offset += size;
- emit_gc_param_slot_def (cfg, sp_offset, t);
+ emit_gc_param_slot_def (cfg, sp_offset, orig_type);
}
} else {
argsize = 4;
if (cfg->compute_gc_maps) {
if (argsize == 4) {
/* FIXME: The == STACK_OBJ check might be fragile ? */
- if (sig->hasthis && i == 0 && call->args [i]->type == STACK_OBJ)
+ if (sig->hasthis && i == 0 && call->args [i]->type == STACK_OBJ) {
/* this */
- emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.object_class->byval_arg);
- else
- emit_gc_param_slot_def (cfg, sp_offset, t);
+ if (call->need_unbox_trampoline)
+ /* The unbox trampoline transforms this into a managed pointer */
+ emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.int_class->this_arg);
+ else
+ emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.object_class->byval_arg);
+ } else {
+ emit_gc_param_slot_def (cfg, sp_offset, orig_type);
+ }
} else {
/* i8/r8 */
for (j = 0; j < argsize; j += 4)
}
call->stack_usage = cinfo->stack_usage;
+ call->stack_align_amount = cinfo->stack_align_amount;
cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset);
}
#ifdef __APPLE__
static gboolean have_tls_get = FALSE;
static gboolean inited = FALSE;
+ guint32 *ins;
if (inited)
return have_tls_get;
- guint32 *ins = (guint32*)pthread_getspecific;
+ ins = (guint32*)pthread_getspecific;
/*
* We're looking for these two instructions:
*
inited = TRUE;
return have_tls_get;
+#elif defined(TARGET_ANDROID)
+ return FALSE;
#else
return TRUE;
#endif
}
+static guint8*
+mono_x86_emit_tls_set (guint8* code, int sreg, int tls_offset)
+{
+#if defined(__APPLE__)
+ x86_prefix (code, X86_GS_PREFIX);
+ x86_mov_mem_reg (code, tls_gs_offset + (tls_offset * 4), sreg, 4);
+#elif defined(TARGET_WIN32)
+ g_assert_not_reached ();
+#else
+ x86_prefix (code, X86_GS_PREFIX);
+ x86_mov_mem_reg (code, tls_offset, sreg, 4);
+#endif
+ return code;
+}
+
/*
* mono_x86_emit_tls_get:
* @code: buffer to store code to
*/
for (i = 0; i < 6; ++i)
x86_nop (code);
+ /*
+ * Add an additional nop so skipping the bp doesn't cause the ip to point
+ * to another IL offset.
+ */
+ x86_nop (code);
break;
}
case OP_ADDCC:
}
/* Copy arguments on the stack to our argument area */
- for (i = 0; i < call->stack_usage; i += 4) {
+ for (i = 0; i < call->stack_usage - call->stack_align_amount; i += 4) {
x86_mov_reg_membase (code, X86_EAX, X86_ESP, i, 4);
x86_mov_membase_reg (code, X86_EBP, 8 + i, X86_EAX, 4);
}
mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
x86_jump32 (code, 0);
+ ins->flags |= MONO_INST_GC_CALLSITE;
cfg->disable_aot = TRUE;
break;
}
alloc_size = cfg->stack_offset;
pos = 0;
- if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
- /* Might need to attach the thread to the JIT or change the domain for the callback */
- if (appdomain_tls_offset != -1 && lmf_tls_offset != -1) {
- guint8 *buf, *no_domain_branch;
-
- code = mono_x86_emit_tls_get (code, X86_EAX, appdomain_tls_offset);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, GPOINTER_TO_UINT (cfg->domain));
- no_domain_branch = code;
- x86_branch8 (code, X86_CC_NE, 0, 0);
- code = mono_x86_emit_tls_get ( code, X86_EAX, lmf_tls_offset);
- x86_test_reg_reg (code, X86_EAX, X86_EAX);
- buf = code;
- x86_branch8 (code, X86_CC_NE, 0, 0);
- x86_patch (no_domain_branch, code);
- x86_push_imm (code, cfg->domain);
- code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach");
- x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
- x86_patch (buf, code);
-#ifdef TARGET_WIN32
- /* The TLS key actually contains a pointer to the MonoJitTlsData structure */
- /* FIXME: Add a separate key for LMF to avoid this */
- x86_alu_reg_imm (code, X86_ADD, X86_EAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
-#endif
- }
- else {
- if (cfg->compile_aot) {
- /*
- * This goes before the saving of callee saved regs, so save the got reg
- * ourselves.
- */
- x86_push_reg (code, MONO_ARCH_GOT_REG);
- code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL);
- x86_push_imm (code, 0);
- } else {
- x86_push_imm (code, cfg->domain);
- }
- code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach");
- x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
- if (cfg->compile_aot)
- x86_pop_reg (code, MONO_ARCH_GOT_REG);
- }
- }
-
if (method->save_lmf) {
pos += sizeof (MonoLMF);
* through the mono_lmf_addr TLS variable.
*/
/* %eax = previous_lmf */
- x86_prefix (code, X86_GS_PREFIX);
- x86_mov_reg_mem (code, X86_EAX, lmf_tls_offset, 4);
+ code = mono_x86_emit_tls_get (code, X86_EAX, lmf_tls_offset);
/* skip esp + method_info + lmf */
x86_alu_reg_imm (code, X86_SUB, X86_ESP, 12);
cfa_offset += 12;
cfa_offset += 4;
mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
/* new lmf = ESP */
- x86_prefix (code, X86_GS_PREFIX);
- x86_mov_mem_reg (code, lmf_tls_offset, X86_ESP, 4);
+ code = mono_x86_emit_tls_set (code, X86_ESP, lmf_tls_offset);
} else {
/* get the address of lmf for the current thread */
/*
x86_mov_reg_membase (code, X86_ECX, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), 4);
/* lmf = previous_lmf */
- x86_prefix (code, X86_GS_PREFIX);
- x86_mov_mem_reg (code, lmf_tls_offset, X86_ECX, 4);
+ code = mono_x86_emit_tls_set (code, X86_ECX, lmf_tls_offset);
} else {
/* Find a spare register */
switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) {
if (CALLCONV_IS_STDCALL (sig)) {
MonoJitArgumentInfo *arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1));
- stack_to_pop = mono_arch_get_argument_info (sig, sig->param_count, arg_info);
+ stack_to_pop = mono_arch_get_argument_info (cfg->generic_sharing_context, sig, sig->param_count, arg_info);
} else if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret) && (cinfo->ret.storage == ArgOnStack))
stack_to_pop = 4;
else
return TRUE;
}
-/*
- * Support for fast access to the thread-local lmf structure using the GS
- * segment register on NPTL + kernel 2.6.x.
- */
-
-static gboolean tls_offset_inited = FALSE;
-
void
-mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
+mono_arch_finish_init (void)
{
- if (!tls_offset_inited) {
- if (!getenv ("MONO_NO_TLS")) {
+ if (!getenv ("MONO_NO_TLS")) {
#ifdef TARGET_WIN32
- /*
- * We need to init this multiple times, since when we are first called, the key might not
- * be initialized yet.
- */
- appdomain_tls_offset = mono_domain_get_tls_key ();
- lmf_tls_offset = mono_get_jit_tls_key ();
-
- /* Only 64 tls entries can be accessed using inline code */
- if (appdomain_tls_offset >= 64)
- appdomain_tls_offset = -1;
- if (lmf_tls_offset >= 64)
- lmf_tls_offset = -1;
+ /*
+ * We need to init this multiple times, since when we are first called, the key might not
+ * be initialized yet.
+ */
+ appdomain_tls_offset = mono_domain_get_tls_key ();
+ lmf_tls_offset = mono_get_jit_tls_key ();
+
+ /* Only 64 tls entries can be accessed using inline code */
+ if (appdomain_tls_offset >= 64)
+ appdomain_tls_offset = -1;
+ if (lmf_tls_offset >= 64)
+ lmf_tls_offset = -1;
#else
#if MONO_XEN_OPT
- optimize_for_xen = access ("/proc/xen", F_OK) == 0;
+ optimize_for_xen = access ("/proc/xen", F_OK) == 0;
#endif
- tls_offset_inited = TRUE;
- appdomain_tls_offset = mono_domain_get_tls_offset ();
- lmf_tls_offset = mono_get_lmf_tls_offset ();
- lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
+ appdomain_tls_offset = mono_domain_get_tls_offset ();
+ lmf_tls_offset = mono_get_lmf_tls_offset ();
+ lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
#endif
- }
}
}
#endif
}
-/*
- * mono_arch_get_ip_for_breakpoint:
- *
- * See mini-amd64.c for docs.
- */
-guint8*
-mono_arch_get_ip_for_breakpoint (MonoJitInfo *ji, MonoContext *ctx)
-{
- guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
-
- return ip;
-}
-
#define BREAKPOINT_SIZE 6
-/*
- * mono_arch_get_ip_for_single_step:
- *
- * See mini-amd64.c for docs.
- */
-guint8*
-mono_arch_get_ip_for_single_step (MonoJitInfo *ji, MonoContext *ctx)
-{
- guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
-
- /* Size of x86_alu_reg_imm */
- ip += 6;
-
- return ip;
-}
-
/*
* mono_arch_skip_breakpoint:
*
* See mini-amd64.c for docs.
*/
void
-mono_arch_skip_breakpoint (MonoContext *ctx)
+mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji)
{
MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + BREAKPOINT_SIZE);
}