break;
case ArgOnStack:
if (MONO_TYPE_ISSTRUCT (t)) {
- linfo->args [i].storage = LLVMArgVtypeByVal;
+ if (mono_class_value_size (mono_class_from_mono_type (t), NULL) == 0)
+ /* LLVM seems to allocate argument space for empty structures too */
+ linfo->args [i].storage = LLVMArgNone;
+ else
+ linfo->args [i].storage = LLVMArgVtypeByVal;
} else {
linfo->args [i].storage = LLVMArgInIReg;
if (t->byref) {
return code;
}
+gboolean
+mono_x86_have_tls_get (void)
+{
+#ifdef __APPLE__
+ guint32 *ins = (guint32*)pthread_getspecific;
+ /*
+ * We're looking for these two instructions:
+ *
+ * mov 0x4(%esp),%eax
+ * mov %gs:0x48(,%eax,4),%eax
+ */
+ return ins [0] == 0x0424448b && ins [1] == 0x85048b65 && ins [2] == 0x00000048;
+#else
+ return TRUE;
+#endif
+}
+
/*
* mono_x86_emit_tls_get:
* @code: buffer to store code to
guint8*
mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset)
{
-#ifdef TARGET_WIN32
+#if defined(__APPLE__)
+ x86_prefix (code, X86_GS_PREFIX);
+ x86_mov_reg_mem (code, dreg, 0x48 + tls_offset * 4, 4);
+#elif defined(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.
#endif /* MONO_ARCH_SIMD_INTRINSICS */
}
+/*MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD*/
+gpointer
+mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value)
+{
+ int offset;
+ gpointer *sp, old_value;
+ char *bp;
+ const unsigned char *handler;
+
+ /*Decode the first instruction to figure out where did we store the spvar*/
+ /*Our jit MUST generate the following:
+ mov %esp, -?(%ebp)
+ Which is encoded as: 0x89 mod_rm.
+ mod_rm (esp, ebp, imm) which can be: (imm will never be zero)
+ mod (reg + imm8): 01 reg(esp): 100 rm(ebp): 101 -> 01100101 (0x65)
+ mod (reg + imm32): 10 reg(esp): 100 rm(ebp): 101 -> 10100101 (0xA5)
+ */
+ handler = clause->handler_start;
+
+ if (*handler != 0x89)
+ return NULL;
+
+ ++handler;
+
+ if (*handler == 0x65)
+ offset = *(signed char*)(handler + 1);
+ else if (*handler == 0xA5)
+ offset = *(int*)(handler + 1);
+ else
+ return NULL;
+
+ /*Load the spvar*/
+ bp = MONO_CONTEXT_GET_BP (ctx);
+ sp = *(gpointer*)(bp + offset);
+
+ old_value = *sp;
+ if (old_value < ji->code_start || (char*)old_value > ((char*)ji->code_start + ji->code_size))
+ return old_value;
+
+ *sp = new_value;
+
+ return old_value;
+}
+
#if __APPLE__
#define DBG_SIGNAL SIGBUS
#else