@@ -5990,8 +5990,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
5990
5990
likelyHood += 100 - likelyHood * numExactClasses;
5991
5991
}
5992
5992
5993
- addGuardedDevirtualizationCandidate(call, exactMethod, exactCls, exactMethodAttrs, clsAttrs ,
5994
- likelyHood);
5993
+ addGuardedDevirtualizationCandidate(call, exactMethod, exactCls, dvInfo.exactContext, exactMethodAttrs ,
5994
+ clsAttrs, likelyHood);
5995
5995
}
5996
5996
5997
5997
if (call->GetInlineCandidatesCount() == numExactClasses)
@@ -6018,6 +6018,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
6018
6018
CORINFO_METHOD_HANDLE likelyMethod = likelyMethodes[candidateId];
6019
6019
unsigned likelihood = likelihoods[candidateId];
6020
6020
6021
+ CORINFO_CONTEXT_HANDLE likelyContext = NULL;
6022
+
6021
6023
uint32_t likelyClassAttribs = 0;
6022
6024
if (likelyClass != NO_CLASS_HANDLE)
6023
6025
{
@@ -6053,7 +6055,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
6053
6055
break;
6054
6056
}
6055
6057
6056
- likelyMethod = dvInfo.devirtualizedMethod;
6058
+ likelyContext = dvInfo.exactContext;
6059
+ likelyMethod = dvInfo.devirtualizedMethod;
6057
6060
}
6058
6061
6059
6062
uint32_t likelyMethodAttribs = info.compCompHnd->getMethodAttribs(likelyMethod);
@@ -6121,8 +6124,8 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
6121
6124
6122
6125
// Add this as a potential candidate.
6123
6126
//
6124
- addGuardedDevirtualizationCandidate(call, likelyMethod, likelyClass, likelyMethodAttribs, likelyClassAttribs ,
6125
- likelihood);
6127
+ addGuardedDevirtualizationCandidate(call, likelyMethod, likelyClass, likelyContext, likelyMethodAttribs ,
6128
+ likelyClassAttribs, likelihood);
6126
6129
}
6127
6130
}
6128
6131
@@ -6147,12 +6150,13 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
6147
6150
// classAttr - attributes of the class
6148
6151
// likelihood - odds that this class is the class seen at runtime
6149
6152
//
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)
6156
6160
{
6157
6161
// This transformation only makes sense for delegate and virtual calls
6158
6162
assert(call->IsDelegateInvoke() || call->IsVirtual());
@@ -6225,6 +6229,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
6225
6229
pInfo->guardedClassHandle = classHandle;
6226
6230
pInfo->likelihood = likelihood;
6227
6231
pInfo->requiresInstMethodTableArg = false;
6232
+ pInfo->exactContextHnd = contextHandle;
6228
6233
6229
6234
// If the guarded class is a value class, look for an unboxed entry point.
6230
6235
//
@@ -6286,8 +6291,14 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode,
6286
6291
{
6287
6292
InlineResult inlineResult(this, call, nullptr, "impMarkInlineCandidate for GDV");
6288
6293
6294
+ CORINFO_CONTEXT_HANDLE moreExactContext = call->GetGDVCandidateInfo(candidateId)->exactContextHnd;
6295
+ if (moreExactContext == NULL)
6296
+ {
6297
+ moreExactContext = exactContextHnd;
6298
+ }
6299
+
6289
6300
// Do the actual evaluation
6290
- impMarkInlineCandidateHelper(call, candidateId, exactContextHnd , exactContextNeedsRuntimeLookup, callInfo,
6301
+ impMarkInlineCandidateHelper(call, candidateId, moreExactContext , exactContextNeedsRuntimeLookup, callInfo,
6291
6302
ilOffset, &inlineResult);
6292
6303
// Ignore non-inlineable candidates
6293
6304
// TODO: Consider keeping them to just devirtualize without inlining, at least for interface
0 commit comments