X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-amd64-gsharedvt.c;h=a4143e8a34494d926f21f4276b166100aca50eb3;hb=3e6c4f526499a339783cbe427e9916bbd99d7a0e;hp=c3e2e99bc861f879e695351b5a8e34c634f95e86;hpb=1c385f99e1c5e5c76e03c49e838ac29739a2e9e2;p=mono.git diff --git a/mono/mini/mini-amd64-gsharedvt.c b/mono/mini/mini-amd64-gsharedvt.c index c3e2e99bc86..a4143e8a344 100644 --- a/mono/mini/mini-amd64-gsharedvt.c +++ b/mono/mini/mini-amd64-gsharedvt.c @@ -1,10 +1,12 @@ -/* - * mini-amd64-gsharedvt.c: libcorkscrew-based native unwinder +/** + * \file + * libcorkscrew-based native unwinder * * Authors: * Zoltan Varga * Rodrigo Kumpera * Andi McClure + * Johan Lorensson * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) * Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -16,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -48,6 +49,7 @@ storage_name (ArgStorage st) case ArgOnStack: return "ArgOnStack"; case ArgValuetypeInReg: return "ArgValuetypeInReg"; case ArgValuetypeAddrInIReg: return "ArgValuetypeAddrInIReg"; + case ArgValuetypeAddrOnStack: return "ArgValuetypeAddrOnStack"; case ArgGSharedVtInReg: return "ArgGSharedVtInReg"; case ArgGSharedVtOnStack: return "ArgGSharedVtOnStack"; case ArgNone: return "ArgNone"; @@ -80,9 +82,17 @@ add_to_map (GPtrArray *map, int src, int dst) /* * Slot mapping: + * + * System V: * 0..5 - rdi, rsi, rdx, rcx, r8, r9 * 6..13 - xmm0..xmm7 * 14.. - stack slots + * + * Windows: + * 0..3 - rcx, rdx, r8, r9 + * 4..7 - xmm0..xmm3 + * 8.. - stack slots + * */ static inline int map_reg (int reg) @@ -158,6 +168,18 @@ get_arg_slots (ArgInfo *ainfo, int **out_slots, gboolean is_source_argument) src = g_malloc (nsrc * sizeof (int)); src [0] = map_freg (sreg); break; + case ArgValuetypeAddrInIReg: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_reg (ainfo->pair_regs [0]); + break; + case ArgValuetypeAddrOnStack: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + // is_source_argument adds 2 because we're skipping over the old BBP and the return address + // XXX this is a very fragile setup as changes in alignment for the caller reg array can cause the magic number be 3 + src [0] = map_stack_slot (sslot + (is_source_argument ? 2 : 0)); + break; default: NOT_IMPLEMENTED; break; @@ -187,6 +209,11 @@ handle_marshal_when_src_gsharedvt (ArgInfo *dst_info, int *arg_marshal, int *arg *arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL; *arg_slots = dst_info->nregs; break; + case ArgValuetypeAddrInIReg: + case ArgValuetypeAddrOnStack: + *arg_marshal = GSHAREDVT_ARG_NONE; + *arg_slots = dst_info->nregs; + break; default: NOT_IMPLEMENTED; // Inappropriate value: if dst and src are gsharedvt at once, we shouldn't be here break; @@ -205,6 +232,10 @@ handle_marshal_when_dst_gsharedvt (ArgInfo *src_info, int *arg_marshal) case ArgOnStack: *arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF; break; + case ArgValuetypeAddrInIReg: + case ArgValuetypeAddrOnStack: + *arg_marshal = GSHAREDVT_ARG_NONE; + break; default: NOT_IMPLEMENTED; // See above break; @@ -274,7 +305,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 */ @@ -316,6 +347,10 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si handle_marshal_when_src_gsharedvt (dst_info, &arg_marshal, &arg_slots); handle_map_when_gsharedvt_on_stack (src_info, &nsrc, &src, TRUE); break; + case ArgValuetypeAddrInIReg: + case ArgValuetypeAddrOnStack: + nsrc = get_arg_slots (src_info, &src, TRUE); + break; default: g_error ("Gsharedvt can't handle source arg type %d", (int)src_info->storage); // Inappropriate value: ArgValuetypeAddrInIReg is for returns only } @@ -336,6 +371,10 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si handle_marshal_when_dst_gsharedvt (src_info, &arg_marshal); handle_map_when_gsharedvt_on_stack (dst_info, &ndst, &dst, FALSE); break; + case ArgValuetypeAddrInIReg: + case ArgValuetypeAddrOnStack: + ndst = get_arg_slots (dst_info, &dst, FALSE); + break; default: g_error ("Gsharedvt can't handle dest arg type %d", (int)dst_info->storage); // See above } @@ -356,8 +395,8 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si DEBUG_AMD64_GSHAREDVT_PRINT ("-- return in (%s) out (%s) var_ret %d\n", arg_info_desc (&caller_cinfo->ret), arg_info_desc (&callee_cinfo->ret), var_ret); 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); + /* Both the caller and the callee pass the vtype ret address in r8 (System V) and RCX or RDX (Windows) */ + 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 +409,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 { @@ -403,22 +442,17 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si } else { MonoType *ret = sig->ret; - // Unwrap enums - if (ret->type == MONO_TYPE_VALUETYPE) - ret = mini_type_get_underlying_type (ret); - + ret = mini_type_get_underlying_type (ret); switch (ret->type) { case MONO_TYPE_I1: info->ret_marshal = GSHAREDVT_RET_I1; break; - case MONO_TYPE_BOOLEAN: case MONO_TYPE_U1: info->ret_marshal = GSHAREDVT_RET_U1; break; case MONO_TYPE_I2: info->ret_marshal = GSHAREDVT_RET_I2; break; - case MONO_TYPE_CHAR: case MONO_TYPE_U2: info->ret_marshal = GSHAREDVT_RET_U2; break; @@ -432,16 +466,15 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si case MONO_TYPE_U: case MONO_TYPE_PTR: case MONO_TYPE_FNPTR: - case MONO_TYPE_CLASS: case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: case MONO_TYPE_U8: case MONO_TYPE_I8: info->ret_marshal = GSHAREDVT_RET_I8; break; - + case MONO_TYPE_GENERICINST: + g_assert (!mono_type_generic_inst_is_valuetype (ret)); + info->ret_marshal = GSHAREDVT_RET_I8; + break; default: g_error ("Gsharedvt can't handle dst type [%d]", (int)sig->ret->type); } @@ -471,8 +504,11 @@ mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_si info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + g_free (callee_cinfo); + g_free (caller_cinfo); + DEBUG_AMD64_GSHAREDVT_PRINT ("allocated an info at %p stack usage %d\n", info, info->stack_usage); return info; } -#endif \ No newline at end of file +#endif