#define optimize_for_xen 0
#endif
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
static gboolean is_win32 = TRUE;
#else
static gboolean is_win32 = FALSE;
#define ARGS_OFFSET 8
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
/* Under windows, the default pinvoke calling convention is stdcall */
#define CALLCONV_IS_STDCALL(sig) ((((sig)->call_convention) == MONO_CALL_STDCALL) || ((sig)->pinvoke && ((sig)->call_convention) == MONO_CALL_DEFAULT))
#else
static X86_Reg_No param_regs [] = { 0 };
-#if defined(PLATFORM_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(TARGET_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
#define SMALL_STRUCTS_IN_REGS
static X86_Reg_No return_regs [] = { X86_EAX, X86_EDX };
#endif
* For x86 win32, see ???.
*/
static CallInfo*
-get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info_internal (MonoGenericSharingContext *gsctx, CallInfo *cinfo, MonoMethodSignature *sig, gboolean is_pinvoke)
{
guint32 i, gr, fr;
MonoType *ret_type;
int n = sig->hasthis + sig->param_count;
guint32 stack_size = 0;
- CallInfo *cinfo;
-
- if (mp)
- cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
- else
- cinfo = g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n));
gr = 0;
fr = 0;
return cinfo;
}
+static CallInfo*
+get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
+{
+ int n = sig->hasthis + sig->param_count;
+ CallInfo *cinfo;
+
+ if (mp)
+ cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
+ else
+ cinfo = g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n));
+
+ return get_call_info_internal (gsctx, cinfo, sig, is_pinvoke);
+}
+
/*
* mono_arch_get_argument_info:
* @csig: a method signature
* padding. arg_info should be large enought to hold param_count + 1 entries.
*
* Returns the size of the argument area on the stack.
+ * This should be signal safe, since it is called from
+ * mono_arch_find_jit_info_ext ().
+ * FIXME: The metadata calls might not be signal safe.
*/
int
mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
int offset = 8;
CallInfo *cinfo;
- cinfo = get_call_info (NULL, NULL, csig, FALSE);
+ /* Avoid g_malloc as it is not signal safe */
+ cinfo = (CallInfo*)g_newa (guint8*, sizeof (CallInfo) + (sizeof (ArgInfo) * (csig->param_count + 1)));
+
+ cinfo = get_call_info_internal (NULL, cinfo, csig, FALSE);
if (MONO_TYPE_ISSTRUCT (csig->ret) && (cinfo->ret.storage == ArgOnStack)) {
args_size += sizeof (gpointer);
args_size += pad = (align - (args_size & (align - 1))) & (align - 1);
arg_info [k].pad = pad;
- g_free (cinfo);
-
return args_size;
}
/* Allocate locals */
offsets = mono_allocate_stack_slots (cfg, &locals_stack_size, &locals_stack_align);
+ if (locals_stack_size > MONO_ARCH_MAX_FRAME_SIZE) {
+ char *mname = mono_method_full_name (cfg->method, TRUE);
+ cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
+ cfg->exception_message = g_strdup_printf ("Method %s stack is too big.", mname);
+ g_free (mname);
+ return;
+ }
if (locals_stack_align) {
offset += (locals_stack_align - 1);
offset &= ~(locals_stack_align - 1);
int sreg = tree->sreg1;
int need_touch = FALSE;
-#if defined(PLATFORM_WIN32) || defined(MONO_ARCH_SIGSEGV_ON_ALTSTACK)
+#if defined(TARGET_WIN32) || defined(MONO_ARCH_SIGSEGV_ON_ALTSTACK)
need_touch = TRUE;
#endif
guint8*
mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset)
{
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
/*
* See the Under the Hood article in the May 1996 issue of Microsoft Systems
* Journal and/or a disassembly of the TlsGet () function.
case OP_NOT_NULL:
break;
case OP_SEQ_POINT: {
- int i, il_offset;
+ int i;
if (cfg->compile_aot)
NOT_IMPLEMENTED;
if (ins->flags & MONO_INST_SINGLE_STEP_LOC)
x86_alu_reg_mem (code, X86_CMP, X86_EAX, (guint32)ss_trigger_page);
- il_offset = ins->inst_imm;
+ mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
- if (!cfg->seq_points)
- cfg->seq_points = g_ptr_array_new ();
- g_ptr_array_add (cfg->seq_points, GUINT_TO_POINTER (il_offset));
- g_ptr_array_add (cfg->seq_points, GUINT_TO_POINTER (code - cfg->native_code));
/*
* A placeholder for a possible breakpoint inserted by
* mono_arch_set_breakpoint ().
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 PLATFORM_WIN32
+#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));
if (lmf_addr_tls_offset != -1) {
/* Load lmf quicky using the GS register */
code = mono_x86_emit_tls_get (code, X86_EAX, lmf_addr_tls_offset);
-#ifdef PLATFORM_WIN32
+#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));
if (alloc_size) {
/* See mono_emit_stack_alloc */
-#if defined(PLATFORM_WIN32) || defined(MONO_ARCH_SIGSEGV_ON_ALTSTACK)
+#if defined(TARGET_WIN32) || defined(MONO_ARCH_SIGSEGV_ON_ALTSTACK)
guint32 remaining_size = alloc_size;
+ /*FIXME handle unbounded code expansion, we should use a loop in case of more than X interactions*/
+ guint32 required_code_size = ((remaining_size / 0x1000) + 1) * 8; /*8 is the max size of x86_alu_reg_imm + x86_test_membase_reg*/
+ guint32 offset = code - cfg->native_code;
+ if (G_UNLIKELY (required_code_size >= (cfg->code_size - offset))) {
+ while (required_code_size >= (cfg->code_size - offset))
+ cfg->code_size *= 2;
+ cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
+ code = cfg->native_code + offset;
+ mono_jit_stats.code_reallocs++;
+ }
while (remaining_size >= 0x1000) {
x86_alu_reg_imm (code, X86_SUB, X86_ESP, 0x1000);
x86_test_membase_reg (code, X86_ESP, 0, X86_ESP);
{
if (!tls_offset_inited) {
if (!getenv ("MONO_NO_TLS")) {
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
/*
* We need to init this multiple times, since when we are first called, the key might not
* be initialized yet.
{
return (MonoMethod*) regs [MONO_ARCH_IMT_REG];
}
-
-MonoObject*
-mono_arch_find_this_argument (mgreg_t *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
-{
- MonoMethodSignature *sig = mono_method_signature (method);
- CallInfo *cinfo = get_call_info (gsctx, NULL, sig, FALSE);
- int this_argument_offset;
- MonoObject *this_argument;
-
- /*
- * this is the offset of the this arg from esp as saved at the start of
- * mono_arch_create_trampoline_code () in tramp-x86.c.
- */
- this_argument_offset = 5;
- if (MONO_TYPE_ISSTRUCT (sig->ret) && (cinfo->ret.storage == ArgOnStack))
- this_argument_offset++;
-
- this_argument = * (MonoObject**) (((guint8*) regs [X86_ESP]) + this_argument_offset * sizeof (gpointer));
-
- g_free (cinfo);
- return this_argument;
-}
#endif
MonoVTable*
return (gpointer)regs [reg];
}
+/*
+ * mono_x86_get_this_arg_offset:
+ *
+ * Return the offset of the stack location where this is passed during a virtual
+ * call.
+ */
+guint32
+mono_x86_get_this_arg_offset (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig)
+{
+ CallInfo *cinfo = NULL;
+ int offset;
+
+ if (MONO_TYPE_ISSTRUCT (sig->ret)) {
+ cinfo = get_call_info (gsctx, NULL, sig, FALSE);
+
+ offset = cinfo->args [0].offset;
+ } else {
+ offset = 0;
+ }
+
+ return offset;
+}
+
gpointer
mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig,
mgreg_t *regs, guint8 *code)
gboolean
mono_arch_is_single_step_event (void *info, void *sigctx)
{
-#ifdef PLATFORM_WIN32
- EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info;
- return FALSE;
+#ifdef TARGET_WIN32
+ EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info; /* Sometimes the address is off by 4 */
+ if ((einfo->ExceptionInformation[1] >= ss_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)ss_trigger_page + 128))
+ return TRUE;
+ else
+ return FALSE;
#else
siginfo_t* sinfo = (siginfo_t*) info;
/* Sometimes the address is off by 4 */
gboolean
mono_arch_is_breakpoint_event (void *info, void *sigctx)
{
-#ifdef PLATFORM_WIN32
- EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info;
- return FALSE;
+#ifdef TARGET_WIN32
+ EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info; /* Sometimes the address is off by 4 */
+ if ((einfo->ExceptionInformation[1] >= bp_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)bp_trigger_page + 128))
+ return TRUE;
+ else
+ return FALSE;
#else
siginfo_t* sinfo = (siginfo_t*)info;
/* Sometimes the address is off by 4 */