ArgumentClass class2 = ARG_CLASS_NO_CLASS;
MonoType *ptype;
- ptype = mono_type_get_underlying_type (type);
+ ptype = mini_type_get_underlying_type (NULL, type);
switch (ptype->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_CHAR:
{
guint32 size, quad, nquads, i;
ArgumentClass args [2];
- MonoMarshalType *info;
+ MonoMarshalType *info = NULL;
MonoClass *klass;
+ MonoGenericSharingContext tmp_gsctx;
+
+ /*
+ * The gsctx currently contains no data, it is only used for checking whenever
+ * open types are allowed, some callers like mono_arch_get_argument_info ()
+ * don't pass it to us, so work around that.
+ */
+ if (!gsctx)
+ gsctx = &tmp_gsctx;
klass = mono_class_from_mono_type (type);
- if (sig->pinvoke)
- size = mono_type_native_stack_size (&klass->byval_arg, NULL);
- else
- size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL);
+ size = mini_type_stack_size_full (gsctx, &klass->byval_arg, NULL, sig->pinvoke);
#ifndef PLATFORM_WIN32
if (!sig->pinvoke && !disable_vtypes_in_regs && ((is_return && (size == 8)) || (!is_return && (size <= 16)))) {
/* We pass and return vtypes of size 8 in a register */
/* return value */
{
- ret_type = mono_type_get_underlying_type (sig->ret);
- ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
+ ret_type = mini_type_get_underlying_type (gsctx, sig->ret);
switch (ret_type->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
add_general (&gr, &stack_size, ainfo);
continue;
}
- ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (gsctx, ptype);
+ ptype = mini_type_get_underlying_type (gsctx, sig->params [i]);
switch (ptype->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
} else
*exclude_mask |= MONO_OPT_CMOV;
}
-#ifdef PLATFORM_WIN32
- /* FIXME */
- *exclude_mask |= (MONO_OPT_PEEPHOLE | MONO_OPT_BRANCH);
-#endif
+
return opts;
}
void
mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
{
- MonoType *ret = mono_type_get_underlying_type (mono_method_signature (method)->ret);
+ MonoType *ret = mini_type_get_underlying_type (NULL, mono_method_signature (method)->ret);
if (!ret->byref) {
if (ret->type == MONO_TYPE_R4) {
#define LOOP_ALIGNMENT 8
#define bb_is_loop_start(bb) ((bb)->loop_body_start && (bb)->nesting)
+#ifndef DISABLE_JIT
+
void
mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
{
mono_debug_open_block (cfg, bb, offset);
+ if (mono_break_at_bb_method && mono_method_desc_full_match (mono_break_at_bb_method, cfg->method) && bb->block_num == mono_break_at_bb_bb_num)
+ x86_breakpoint (code);
+
MONO_BB_FOR_EACH_INS (bb, ins) {
offset = code - cfg->native_code;
case OP_BREAK:
amd64_breakpoint (code);
break;
+ case OP_RELAXED_NOP:
+ x86_prefix (code, X86_REP_PREFIX);
+ x86_nop (code);
+ break;
case OP_NOP:
case OP_DUMMY_USE:
case OP_DUMMY_STORE:
case OP_X86_PUSH_MEMBASE:
amd64_push_membase (code, ins->inst_basereg, ins->inst_offset);
break;
- case OP_X86_PUSH_OBJ:
- amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, ins->inst_imm);
+ case OP_X86_PUSH_OBJ: {
+ int size = ALIGN_TO (ins->inst_imm, 8);
+ amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, size);
amd64_push_reg (code, AMD64_RDI);
amd64_push_reg (code, AMD64_RSI);
amd64_push_reg (code, AMD64_RCX);
amd64_lea_membase (code, AMD64_RSI, ins->inst_basereg, ins->inst_offset);
else
amd64_mov_reg_reg (code, AMD64_RSI, ins->inst_basereg, 8);
- amd64_lea_membase (code, AMD64_RDI, AMD64_RSP, 3 * 8);
+ amd64_lea_membase (code, AMD64_RDI, AMD64_RSP, (3 * 8) + (size - ins->inst_imm));
amd64_mov_reg_imm (code, AMD64_RCX, (ins->inst_imm >> 3));
amd64_cld (code);
amd64_prefix (code, X86_REP_PREFIX);
amd64_pop_reg (code, AMD64_RSI);
amd64_pop_reg (code, AMD64_RDI);
break;
+ }
case OP_X86_LEA:
amd64_lea_memindex (code, ins->dreg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->backend.shift_amount);
break;
cfg->code_len = code - cfg->native_code;
}
+#endif /* DISABLE_JIT */
+
void
mono_arch_register_lowlevel_calls (void)
{
pos = 0;
if (method->save_lmf) {
+ /* check if we need to restore protection of the stack after a stack overflow */
+ if (mono_get_jit_tls_offset () != -1) {
+ guint8 *patch;
+ code = emit_tls_get (code, X86_ECX, mono_get_jit_tls_offset ());
+ /* we load the value in a separate instruction: this mechanism may be
+ * used later as a safer way to do thread interruption
+ */
+ amd64_mov_reg_membase (code, X86_ECX, X86_ECX, G_STRUCT_OFFSET (MonoJitTlsData, restore_stack_prot), 8);
+ x86_alu_reg_imm (code, X86_CMP, X86_ECX, 0);
+ patch = code;
+ x86_branch8 (code, X86_CC_Z, 0, FALSE);
+ /* note that the call trampoline will preserve eax/edx */
+ x86_call_reg (code, X86_ECX);
+ x86_patch (patch, code);
+ } else {
+ /* FIXME: maybe save the jit tls in the prolog */
+ }
if ((lmf_tls_offset != -1) && !optimize_for_xen) {
/*
* Optimized version which uses the mono_lmf TLS variable instead of indirection
for (quad = 0; quad < 2; quad ++) {
switch (ainfo->pair_storage [quad]) {
case ArgInIReg:
+ /* check if we need to restore protection of the stack after a stack overflow */
+ if (mono_get_jit_tls_offset () != -1) {
+ guint8 *patch;
+ code = emit_tls_get (code, X86_ECX, mono_get_jit_tls_offset ());
+ /* we load the value in a separate instruction: this mechanism may be
+ * used later as a safer way to do thread interruption
+ */
+ x86_mov_reg_membase (code, X86_ECX, X86_ECX, G_STRUCT_OFFSET (MonoJitTlsData, restore_stack_prot), 4);
+ x86_alu_reg_imm (code, X86_CMP, X86_ECX, 0);
+ patch = code;
+ x86_branch8 (code, X86_CC_Z, 0, FALSE);
+ /* note that the call trampoline will preserve eax/edx */
+ x86_call_reg (code, X86_ECX);
+ x86_patch (patch, code);
+ } else {
+ /* FIXME: maybe save the jit tls in the prolog */
+ }
amd64_mov_reg_membase (code, ainfo->pair_regs [quad], inst->inst_basereg, inst->inst_offset + (quad * sizeof (gpointer)), sizeof (gpointer));
break;
case ArgInFloatSSEReg:
guchar *code = p;
int save_mode = SAVE_NONE;
MonoMethod *method = cfg->method;
- int rtype = mono_type_get_underlying_type (mono_method_signature (method)->ret)->type;
+ int rtype = mini_type_get_underlying_type (NULL, mono_method_signature (method)->ret)->type;
switch (rtype) {
case MONO_TYPE_VOID:
} else {
/* We have to shift the arguments left */
amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
- for (i = 0; i < sig->param_count; ++i)
+ for (i = 0; i < sig->param_count; ++i) {
+#ifdef PLATFORM_WIN32
+ if (i < 3)
+ amd64_mov_reg_reg (code, param_regs [i], param_regs [i + 1], 8);
+ else
+ amd64_mov_reg_membase (code, param_regs [i], AMD64_RSP, 0x28, 8);
+#else
amd64_mov_reg_reg (code, param_regs [i], param_regs [i + 1], 8);
+#endif
+ }
amd64_jump_membase (code, AMD64_RAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
}
}
void
-mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call)
+mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg)
{
/* Done by the implementation of the CALL_MEMBASE opcodes */
}