@@ -5990,8 +5990,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
59905990 likelyHood += 100 - likelyHood * numExactClasses;
59915991 }
59925992
5993- addGuardedDevirtualizationCandidate (call, exactMethod, exactCls, exactMethodAttrs, clsAttrs ,
5994- likelyHood);
5993+ addGuardedDevirtualizationCandidate (call, exactMethod, exactCls, dvInfo. exactContext , exactMethodAttrs ,
5994+ clsAttrs, likelyHood);
59955995 }
59965996
59975997 if (call->GetInlineCandidatesCount () == numExactClasses)
@@ -6018,6 +6018,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
60186018 CORINFO_METHOD_HANDLE likelyMethod = likelyMethodes[candidateId];
60196019 unsigned likelihood = likelihoods[candidateId];
60206020
6021+ CORINFO_CONTEXT_HANDLE likelyContext = NULL ;
6022+
60216023 uint32_t likelyClassAttribs = 0 ;
60226024 if (likelyClass != NO_CLASS_HANDLE)
60236025 {
@@ -6053,7 +6055,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
60536055 break ;
60546056 }
60556057
6056- likelyMethod = dvInfo.devirtualizedMethod ;
6058+ likelyContext = dvInfo.exactContext ;
6059+ likelyMethod = dvInfo.devirtualizedMethod ;
60576060 }
60586061
60596062 uint32_t likelyMethodAttribs = info.compCompHnd ->getMethodAttribs (likelyMethod);
@@ -6121,8 +6124,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
61216124
61226125 // Add this as a potential candidate.
61236126 //
6124- addGuardedDevirtualizationCandidate (call, likelyMethod, likelyClass, likelyMethodAttribs, likelyClassAttribs ,
6125- likelihood);
6127+ addGuardedDevirtualizationCandidate (call, likelyMethod, likelyClass, likelyContext, likelyMethodAttribs ,
6128+ likelyClassAttribs, likelihood);
61266129 }
61276130}
61286131
@@ -6147,12 +6150,13 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
61476150// classAttr - attributes of the class
61486151// likelihood - odds that this class is the class seen at runtime
61496152//
6150- void Compiler::addGuardedDevirtualizationCandidate (GenTreeCall* call,
6151- CORINFO_METHOD_HANDLE methodHandle,
6152- CORINFO_CLASS_HANDLE classHandle,
6153- unsigned methodAttr,
6154- unsigned classAttr,
6155- unsigned likelihood)
6153+ void Compiler::addGuardedDevirtualizationCandidate (GenTreeCall* call,
6154+ CORINFO_METHOD_HANDLE methodHandle,
6155+ CORINFO_CLASS_HANDLE classHandle,
6156+ CORINFO_CONTEXT_HANDLE contextHandle,
6157+ unsigned methodAttr,
6158+ unsigned classAttr,
6159+ unsigned likelihood)
61566160{
61576161 // This transformation only makes sense for delegate and virtual calls
61586162 assert (call->IsDelegateInvoke () || call->IsVirtual ());
@@ -6225,6 +6229,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
62256229 pInfo->guardedClassHandle = classHandle;
62266230 pInfo->likelihood = likelihood;
62276231 pInfo->requiresInstMethodTableArg = false ;
6232+ pInfo->exactContextHnd = contextHandle;
62286233
62296234 // If the guarded class is a value class, look for an unboxed entry point.
62306235 //
@@ -6286,8 +6291,14 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode,
62866291 {
62876292 InlineResult inlineResult (this , call, nullptr , " impMarkInlineCandidate for GDV" );
62886293
6294+ CORINFO_CONTEXT_HANDLE moreExactContext = call->GetGDVCandidateInfo (candidateId)->exactContextHnd ;
6295+ if (moreExactContext == NULL )
6296+ {
6297+ moreExactContext = exactContextHnd;
6298+ }
6299+
62896300 // Do the actual evaluation
6290- impMarkInlineCandidateHelper (call, candidateId, exactContextHnd , exactContextNeedsRuntimeLookup, callInfo,
6301+ impMarkInlineCandidateHelper (call, candidateId, moreExactContext , exactContextNeedsRuntimeLookup, callInfo,
62916302 ilOffset, &inlineResult);
62926303 // Ignore non-inlineable candidates
62936304 // TODO: Consider keeping them to just devirtualize without inlining, at least for interface
0 commit comments