summaryrefslogtreecommitdiff
path: root/src/vm/method.cpp
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2019-05-23 21:24:44 -0700
committerGitHub <noreply@github.com>2019-05-23 21:24:44 -0700
commitd5d18896900561b7aaf38ba9501a8525a4b9caea (patch)
tree60f975b42a41b38562b2cb0324f2dcc923036ecf /src/vm/method.cpp
parent267f8299ac1fd97430284fa6d44e5e9c6ed26850 (diff)
downloadcoreclr-d5d18896900561b7aaf38ba9501a8525a4b9caea.tar.gz
coreclr-d5d18896900561b7aaf38ba9501a8525a4b9caea.tar.bz2
coreclr-d5d18896900561b7aaf38ba9501a8525a4b9caea.zip
Delete RETURNTYPE and change how we get ReturnKind for gccover. (#24600)
* Move GetReturnKindFromMethodTable to method.hpp. We would need this in other places in the next commits. * Delete unnecessary checks from callhelpers. * Do not check return types in CanDeduplicateCode. GC info v.2 has this information and it is checked in another place. * Change ComPlusMethodFrame to use the new function. * Change gccover.cpp to use GetReturnKindFromMethodTable. * Delete RETURNTYPE. * Add check to ComPlusMethodFrame. * Delete check from threadsuspend. codeInfo->GetCodeManager()->GetReturnKind(gcInfoToken) must always return a valid kind nowdays (it could return an invalid lind only when GC Info v2 was not available). * Rename functions/arguments. * Add check for IsValidReturnKind. * delete unused var.
Diffstat (limited to 'src/vm/method.cpp')
-rw-r--r--src/vm/method.cpp76
1 files changed, 58 insertions, 18 deletions
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index 06cdc06c00..c17901582f 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -1213,12 +1213,7 @@ COR_ILMETHOD* MethodDesc::GetILHeader(BOOL fAllowOverrides /*=FALSE*/)
}
//*******************************************************************************
-MetaSig::RETURNTYPE MethodDesc::ReturnsObject(
-#ifdef _DEBUG
- bool supportStringConstructors,
-#endif
- MethodTable** pMT
- )
+ReturnKind MethodDesc::ParseReturnKindFromSig(INDEBUG(bool supportStringConstructors))
{
CONTRACTL
{
@@ -1243,7 +1238,7 @@ MetaSig::RETURNTYPE MethodDesc::ReturnsObject(
case ELEMENT_TYPE_ARRAY:
case ELEMENT_TYPE_OBJECT:
case ELEMENT_TYPE_VAR:
- return(MetaSig::RETOBJ);
+ return RT_Object;
#ifdef ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE
case ELEMENT_TYPE_VALUETYPE:
@@ -1258,22 +1253,39 @@ MetaSig::RETURNTYPE MethodDesc::ReturnsObject(
if (!thValueType.IsTypeDesc())
{
MethodTable * pReturnTypeMT = thValueType.AsMethodTable();
- if (pMT != NULL)
- {
- *pMT = pReturnTypeMT;
- }
-
#ifdef UNIX_AMD64_ABI
if (pReturnTypeMT->IsRegPassedStruct())
{
- return MetaSig::RETVALUETYPE;
+ // The Multi-reg return case using the classhandle is only implemented for AMD64 SystemV ABI.
+ // On other platforms, multi-reg return is not supported with GcInfo v1.
+ // So, the relevant information must be obtained from the GcInfo tables (which requires version2).
+ EEClass* eeClass = pReturnTypeMT->GetClass();
+ ReturnKind regKinds[2] = { RT_Unset, RT_Unset };
+ int orefCount = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ if (eeClass->GetEightByteClassification(i) == SystemVClassificationTypeIntegerReference)
+ {
+ regKinds[i] = RT_Object;
+ }
+ else if (eeClass->GetEightByteClassification(i) == SystemVClassificationTypeIntegerByRef)
+ {
+ regKinds[i] = RT_ByRef;
+ }
+ else
+ {
+ regKinds[i] = RT_Scalar;
+ }
+ }
+ ReturnKind structReturnKind = GetStructReturnKind(regKinds[0], regKinds[1]);
+ return structReturnKind;
}
-#endif // !UNIX_AMD64_ABI
+#endif // UNIX_AMD64_ABI
if (pReturnTypeMT->ContainsPointers())
{
_ASSERTE(pReturnTypeMT->GetNumInstanceFieldBytes() == sizeof(void*));
- return MetaSig::RETOBJ;
+ return RT_Object;
}
}
}
@@ -1290,19 +1302,47 @@ MetaSig::RETURNTYPE MethodDesc::ReturnsObject(
if (IsCtor() && GetMethodTable()->HasComponentSize())
{
_ASSERTE(supportStringConstructors);
- return MetaSig::RETOBJ;
+ return RT_Object;
}
break;
#endif // _DEBUG
case ELEMENT_TYPE_BYREF:
- return(MetaSig::RETBYREF);
+ return RT_ByRef;
default:
break;
}
- return(MetaSig::RETNONOBJ);
+ return RT_Scalar;
+}
+
+ReturnKind MethodDesc::GetReturnKind(INDEBUG(bool supportStringConstructors))
+{
+#ifdef _WIN64
+ // For simplicity, we don't hijack in funclets, but if you ever change that,
+ // be sure to choose the OnHijack... callback type to match that of the FUNCLET
+ // not the main method (it would probably be Scalar).
+#endif // _WIN64
+
+ ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
+ // Mark that we are performing a stackwalker like operation on the current thread.
+ // This is necessary to allow the signature parsing functions to work without triggering any loads
+ ClrFlsValueSwitch threadStackWalking(TlsIdx_StackWalkerWalkingThread, GetThread());
+
+#ifdef _TARGET_X86_
+ MetaSig msig(this);
+ if (msig.HasFPReturn())
+ {
+ // Figuring out whether the function returns FP or not is hard to do
+ // on-the-fly, so we use a different callback helper on x86 where this
+ // piece of information is needed in order to perform the right save &
+ // restore of the return value around the call to OnHijackScalarWorker.
+ return RT_Float;
+ }
+#endif // _TARGET_X86_
+
+ return ParseReturnKindFromSig(INDEBUG(supportStringConstructors));
}
#ifdef FEATURE_COMINTEROP