diff options
author | Sergey Andreenko <seandree@microsoft.com> | 2019-05-23 21:24:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-23 21:24:44 -0700 |
commit | d5d18896900561b7aaf38ba9501a8525a4b9caea (patch) | |
tree | 60f975b42a41b38562b2cb0324f2dcc923036ecf /src/vm/method.cpp | |
parent | 267f8299ac1fd97430284fa6d44e5e9c6ed26850 (diff) | |
download | coreclr-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.cpp | 76 |
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 |