[amd64] Add a separate ArgStorage entry for gsharedvt return types instead of using...
authorZoltan Varga <vargaz@gmail.com>
Sun, 3 Apr 2016 01:02:50 +0000 (21:02 -0400)
committerZoltan Varga <vargaz@gmail.com>
Sun, 3 Apr 2016 01:02:57 +0000 (21:02 -0400)
mono/mini/mini-amd64-gsharedvt.c
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h

index c3e2e99bc861f879e695351b5a8e34c634f95e86..dffa9370f27024990fe7e52ab6a01d3128ca4498 100644 (file)
@@ -274,7 +274,7 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si
        DEBUG_AMD64_GSHAREDVT_PRINT ("source sig: (%s) return (%s)\n", mono_signature_get_desc (caller_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (caller_sig))); // Leak
        DEBUG_AMD64_GSHAREDVT_PRINT ("dest sig: (%s) return (%s)\n", mono_signature_get_desc (callee_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (callee_sig)));
 
-       if (gcinfo->ret.is_gsharedvt_return_value) {
+       if (gcinfo->ret.storage == ArgGsharedvtVariableInReg) {
                /*
                 * The return type is gsharedvt
                 */
@@ -357,7 +357,7 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si
 
        if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
                /* Both the caller and the callee pass the vtype ret address in r8 */
-               g_assert (cinfo->ret.storage == gcinfo->ret.storage);
+               g_assert (gcinfo->ret.storage == ArgValuetypeAddrInIReg || gcinfo->ret.storage == ArgGsharedvtVariableInReg);
                add_to_map (map, map_reg (cinfo->ret.reg), map_reg (cinfo->ret.reg));
        }
 
@@ -370,7 +370,7 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si
        info->calli = calli;
 
        if (var_ret) {
-               g_assert (gcinfo->ret.is_gsharedvt_return_value);
+               g_assert (gcinfo->ret.storage == ArgGsharedvtVariableInReg);
                info->vret_arg_reg = map_reg (gcinfo->ret.reg);
                DEBUG_AMD64_GSHAREDVT_PRINT ("mapping vreg_arg_reg to %d in reg %s\n", info->vret_arg_reg, mono_arch_regname (gcinfo->ret.reg));
        } else {
@@ -475,4 +475,4 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si
        return info;
 }
 
-#endif
\ No newline at end of file
+#endif
index 18e48283d95cf103e25714f8d4478a8276a654f8..901a6c99d76554f74d5ef72cec3a828b6e0802c8 100644 (file)
@@ -1108,6 +1108,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                cinfo = (CallInfo *)g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n));
 
        cinfo->nargs = n;
+       cinfo->gsharedvt = mini_is_gsharedvt_variable_signature (sig);
 
        gr = 0;
        fr = 0;
@@ -1158,8 +1159,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                        break;
                }
                if (mini_is_gsharedvt_type (ret_type)) {
-                       cinfo->ret.storage = ArgValuetypeAddrInIReg;
-                       cinfo->ret.is_gsharedvt_return_value = 1;
+                       cinfo->ret.storage = ArgGsharedvtVariableInReg;
                        break;
                }
                /* fall through */
@@ -1174,8 +1174,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                g_assert (mini_is_gsharedvt_type (ret_type));
-               cinfo->ret.storage = ArgValuetypeAddrInIReg;
-               cinfo->ret.is_gsharedvt_return_value = 1;
+               cinfo->ret.storage = ArgGsharedvtVariableInReg;
                break;
        case MONO_TYPE_VOID:
                break;
@@ -1191,7 +1190,8 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
         * are sometimes made using calli without sig->hasthis set, like in the delegate
         * invoke wrappers.
         */
-       if (cinfo->ret.storage == ArgValuetypeAddrInIReg && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) {
+       ArgStorage ret_storage = cinfo->ret.storage;
+       if ((ret_storage == ArgValuetypeAddrInIReg || ret_storage == ArgGsharedvtVariableInReg) && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) {
                if (sig->hasthis) {
                        add_general (&gr, &stack_size, cinfo->args + 0);
                } else {
@@ -1199,16 +1199,16 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                        pstart = 1;
                }
                add_general (&gr, &stack_size, &cinfo->ret);
-               cinfo->ret.storage = ArgValuetypeAddrInIReg;
+               cinfo->ret.storage = ret_storage;
                cinfo->vret_arg_index = 1;
        } else {
                /* this */
                if (sig->hasthis)
                        add_general (&gr, &stack_size, cinfo->args + 0);
 
-               if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
+               if (ret_storage == ArgValuetypeAddrInIReg || ret_storage == ArgGsharedvtVariableInReg) {
                        add_general (&gr, &stack_size, &cinfo->ret);
-                       cinfo->ret.storage = ArgValuetypeAddrInIReg;
+                       cinfo->ret.storage = ret_storage;
                }
        }
 
@@ -1865,6 +1865,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                        cfg->ret->dreg = cinfo->ret.reg;
                        break;
                case ArgValuetypeAddrInIReg:
+               case ArgGsharedvtVariableInReg:
                        /* The register is volatile */
                        cfg->vret_addr->opcode = OP_REGOFFSET;
                        cfg->vret_addr->inst_basereg = cfg->frame_reg;
@@ -2042,7 +2043,7 @@ mono_arch_create_vars (MonoCompile *cfg)
                cfg->ret_var_is_local = TRUE;
 
        sig_ret = mini_get_underlying_type (sig->ret);
-       if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
+       if (cinfo->ret.storage == ArgValuetypeAddrInIReg || cinfo->ret.storage == ArgGsharedvtVariableInReg) {
                cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
                if (G_UNLIKELY (cfg->verbose_level > 1)) {
                        printf ("vret_addr = ");
@@ -2230,6 +2231,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
                break;
        }
        case ArgValuetypeAddrInIReg:
+       case ArgGsharedvtVariableInReg:
                /* Vtype returned using a hidden argument */
                linfo->ret.storage = LLVMArgVtypeRetAddr;
                linfo->vret_arg_index = cinfo->vret_arg_index;
@@ -2479,7 +2481,8 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                        MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ((MonoInst*)cfg->arch.vret_addr_loc)->dreg, call->vret_var->dreg);
                }
                break;
-       case ArgValuetypeAddrInIReg: {
+       case ArgValuetypeAddrInIReg:
+       case ArgGsharedvtVariableInReg: {
                MonoInst *vtarg;
                MONO_INST_NEW (cfg, vtarg, OP_MOVE);
                vtarg->sreg1 = call->vret_var->dreg;
@@ -2770,7 +2773,7 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
                        pindex = 1;
        }
 
-       if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg)
+       if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg || dinfo->cinfo->ret.storage == ArgGsharedvtVariableInReg)
                p->regs [greg ++] = PTR_TO_GREG(ret);
 
        for (i = pindex; i < sig->param_count; i++) {
@@ -2951,7 +2954,7 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf)
                        /* Fall through */
                }
        case MONO_TYPE_VALUETYPE:
-               if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg) {
+               if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg || dinfo->cinfo->ret.storage == ArgGsharedvtVariableInReg) {
                        /* Nothing to do */
                } else {
                        ArgInfo *ainfo = &dinfo->cinfo->ret;
index c22c9be0fd0007b3969fc7beec42ac686e66e0d9..1d04234c1785f7d5eb0045764bc3212a81cdfc42 100644 (file)
@@ -275,6 +275,8 @@ typedef enum {
        /* gsharedvt argument passed by addr */
        ArgGSharedVtInReg,
        ArgGSharedVtOnStack,
+       /* Variable sized gsharedvt argument passed/returned by addr */
+       ArgGsharedvtVariableInReg,
        ArgNone /* only in pair_storage */
 } ArgStorage;
 
@@ -282,7 +284,6 @@ typedef struct {
        gint16 offset;
        gint8  reg;
        ArgStorage storage : 8;
-       gboolean is_gsharedvt_return_value : 1;
 
        /* Only if storage == ArgValuetypeInReg */
        ArgStorage pair_storage [2];
@@ -300,6 +301,7 @@ typedef struct {
        guint32 reg_usage;
        guint32 freg_usage;
        gboolean need_stack_align;
+       gboolean gsharedvt;
        /* The index of the vret arg in the argument list */
        int vret_arg_index;
        ArgInfo ret;