Revert "[amd64] More gsharedvt/cleanup work."
authorZoltan Varga <vargaz@gmail.com>
Wed, 16 Sep 2015 16:50:34 +0000 (12:50 -0400)
committerZoltan Varga <vargaz@gmail.com>
Wed, 16 Sep 2015 16:50:53 +0000 (12:50 -0400)
This reverts commit c09ca0fd7ef86f9cd6d591def2fa6a60bc272fa1.

Revert this as it breaks the build.

mono/mini/mini-amd64.c

index 08c545a1422afafb3e7422b78f4453686569113c..6458cf1079aa9314d28b8dde37dd8a12f91995c9 100644 (file)
@@ -2308,57 +2308,57 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                        add_outarg_reg (cfg, call, ainfo->storage, ainfo->reg, in);
                        break;
                case ArgOnStack:
-                       if (call->tail_call) {
-                               MonoInst *call_inst = (MonoInst*)call;
-                               cfg->args [i]->flags |= MONO_INST_VOLATILE;
-                               EMIT_NEW_ARGSTORE (cfg, call_inst, i, in);
-                       }
-                       break;
                case ArgValuetypeInReg:
                case ArgValuetypeAddrInIReg:
                case ArgGSharedVtInReg:
-               case ArgGSharedVtOnStack: {
-                       guint32 align;
-                       guint32 size;
+               case ArgGSharedVtOnStack:
+                       if (ainfo->storage == ArgOnStack && call->tail_call) {
+                               MonoInst *call_inst = (MonoInst*)call;
+                               cfg->args [i]->flags |= MONO_INST_VOLATILE;
+                               EMIT_NEW_ARGSTORE (cfg, call_inst, i, in);
+                       } else if ((i >= sig->hasthis) && (MONO_TYPE_ISSTRUCT(t))) {
+                               guint32 align;
+                               guint32 size;
 
-                       if (t->type == MONO_TYPE_TYPEDBYREF) {
-                               size = sizeof (MonoTypedRef);
-                               align = sizeof (gpointer);
-                       }
-                       else {
-                               if (sig->pinvoke)
-                                       size = mono_type_native_stack_size (t, &align);
+                               if (t->type == MONO_TYPE_TYPEDBYREF) {
+                                       size = sizeof (MonoTypedRef);
+                                       align = sizeof (gpointer);
+                               }
                                else {
-                                       /*
-                                        * Other backends use mono_type_stack_size (), but that
-                                        * aligns the size to 8, which is larger than the size of
-                                        * the source, leading to reads of invalid memory if the
-                                        * source is at the end of address space.
-                                        */
-                                       size = mono_class_value_size (mono_class_from_mono_type (t), &align);
+                                       if (sig->pinvoke)
+                                               size = mono_type_native_stack_size (t, &align);
+                                       else {
+                                               /* 
+                                                * Other backends use mono_type_stack_size (), but that
+                                                * aligns the size to 8, which is larger than the size of
+                                                * the source, leading to reads of invalid memory if the
+                                                * source is at the end of address space.
+                                                */
+                                               size = mono_class_value_size (mono_class_from_mono_type (t), &align);
+                                       }
                                }
-                       }
+                               g_assert (in->klass);
 
-                       if (size >= 10000) {
-                               /* Avoid asserts in emit_memcpy () */
-                               cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
-                               cfg->exception_message = g_strdup_printf ("Passing an argument of size '%d'.", size);
-                               /* Continue normally */
-                       }
+                               if (ainfo->storage == ArgOnStack && size >= 10000) {
+                                       /* Avoid asserts in emit_memcpy () */
+                                       cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
+                                       cfg->exception_message = g_strdup_printf ("Passing an argument of size '%d'.", size);
+                                       /* Continue normally */
+                               }
 
-                       if (size > 0) {
-                               MONO_INST_NEW (cfg, arg, OP_OUTARG_VT);
-                               arg->sreg1 = in->dreg;
-                               arg->klass = mono_class_from_mono_type (t);
-                               arg->backend.size = size;
-                               arg->inst_p0 = call;
-                               arg->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
-                               memcpy (arg->inst_p1, ainfo, sizeof (ArgInfo));
+                               if (size > 0) {
+                                       MONO_INST_NEW (cfg, arg, OP_OUTARG_VT);
+                                       arg->sreg1 = in->dreg;
+                                       arg->klass = mono_class_from_mono_type (t);
+                                       arg->backend.size = size;
+                                       arg->inst_p0 = call;
+                                       arg->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
+                                       memcpy (arg->inst_p1, ainfo, sizeof (ArgInfo));
 
-                               MONO_ADD_INS (cfg->cbb, arg);
+                                       MONO_ADD_INS (cfg->cbb, arg);
+                               }
                        }
                        break;
-               }
                default:
                        g_assert_not_reached ();
                }
@@ -2372,50 +2372,49 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sig->sentinelpos))
                emit_sig_cookie (cfg, call, cinfo);
 
-       switch (cinfo->ret.storage) {
-       case ArgValuetypeInReg:
-               if (cinfo->ret.pair_storage [0] == ArgInIReg && cinfo->ret.pair_storage [1] == ArgNone) {
-                       /*
-                        * Tell the JIT to use a more efficient calling convention: call using
-                        * OP_CALL, compute the result location after the call, and save the
-                        * result there.
-                        */
-                       call->vret_in_reg = TRUE;
-                       /*
-                        * Nullify the instruction computing the vret addr to enable
-                        * future optimizations.
-                        */
-                       if (call->vret_var)
-                               NULLIFY_INS (call->vret_var);
-               } else {
-                       if (call->tail_call)
-                               NOT_IMPLEMENTED;
-                       /*
-                        * The valuetype is in RAX:RDX after the call, need to be copied to
-                        * the stack. Push the address here, so the call instruction can
-                        * access it.
-                        */
-                       if (!cfg->arch.vret_addr_loc) {
-                               cfg->arch.vret_addr_loc = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-                               /* Prevent it from being register allocated or optimized away */
-                               ((MonoInst*)cfg->arch.vret_addr_loc)->flags |= MONO_INST_VOLATILE;
-                       }
+       sig_ret = mini_get_underlying_type (sig->ret);
+       if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) {
+               MonoInst *vtarg;
 
-                       MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ((MonoInst*)cfg->arch.vret_addr_loc)->dreg, call->vret_var->dreg);
+               if (cinfo->ret.storage == ArgValuetypeInReg) {
+                       if (cinfo->ret.pair_storage [0] == ArgInIReg && cinfo->ret.pair_storage [1] == ArgNone) {
+                               /*
+                                * Tell the JIT to use a more efficient calling convention: call using
+                                * OP_CALL, compute the result location after the call, and save the 
+                                * result there.
+                                */
+                               call->vret_in_reg = TRUE;
+                               /* 
+                                * Nullify the instruction computing the vret addr to enable 
+                                * future optimizations.
+                                */
+                               if (call->vret_var)
+                                       NULLIFY_INS (call->vret_var);
+                       } else {
+                               if (call->tail_call)
+                                       NOT_IMPLEMENTED;
+                               /*
+                                * The valuetype is in RAX:RDX after the call, need to be copied to
+                                * the stack. Push the address here, so the call instruction can
+                                * access it.
+                                */
+                               if (!cfg->arch.vret_addr_loc) {
+                                       cfg->arch.vret_addr_loc = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+                                       /* Prevent it from being register allocated or optimized away */
+                                       ((MonoInst*)cfg->arch.vret_addr_loc)->flags |= MONO_INST_VOLATILE;
+                               }
+
+                               MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ((MonoInst*)cfg->arch.vret_addr_loc)->dreg, call->vret_var->dreg);
+                       }
                }
-               break;
-       case ArgValuetypeAddrInIReg: {
-               MonoInst *vtarg;
-               MONO_INST_NEW (cfg, vtarg, OP_MOVE);
-               vtarg->sreg1 = call->vret_var->dreg;
-               vtarg->dreg = mono_alloc_preg (cfg);
-               MONO_ADD_INS (cfg->cbb, vtarg);
+               else {
+                       MONO_INST_NEW (cfg, vtarg, OP_MOVE);
+                       vtarg->sreg1 = call->vret_var->dreg;
+                       vtarg->dreg = mono_alloc_preg (cfg);
+                       MONO_ADD_INS (cfg->cbb, vtarg);
 
-               mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, cinfo->ret.reg, FALSE);
-               break;
-       }
-       default:
-               break;
+                       mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, cinfo->ret.reg, FALSE);
+               }
        }
 
        if (cfg->method->save_lmf) {
@@ -2434,8 +2433,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
        ArgInfo *ainfo = (ArgInfo*)ins->inst_p1;
        int size = ins->backend.size;
 
-       switch (ainfo->storage) {
-       case ArgValuetypeInReg: {
+       if (ainfo->storage == ArgValuetypeInReg) {
                MonoInst *load;
                int part;
 
@@ -2462,9 +2460,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
 
                        add_outarg_reg (cfg, call, ainfo->pair_storage [part], ainfo->pair_regs [part], load);
                }
-               break;
-       }
-       case ArgValuetypeAddrInIReg: {
+       } else if (ainfo->storage == ArgValuetypeAddrInIReg) {
                MonoInst *vtaddr, *load;
                vtaddr = mono_compile_create_var (cfg, &ins->klass->byval_arg, OP_LOCAL);
                
@@ -2488,16 +2484,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
                } else {
                        MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, AMD64_RSP, ainfo->offset, load->dreg);
                }
-               break;
-       }
-       case ArgGSharedVtInReg:
-               /* Pass by addr */
-               mono_call_inst_add_outarg_reg (cfg, call, src->dreg, ainfo->reg, FALSE);
-               break;
-       case ArgGSharedVtOnStack:
-               g_assert_not_reached ();
-               break;
-       default:
+       } else {
                if (size == 8) {
                        int dreg = mono_alloc_ireg (cfg);