Skip to content

Commit 7ebf967

Browse files
Use proper context in initClass for GDV (#87847)
Co-authored-by: David Wrighton <davidwr@microsoft.com>
1 parent d389ab9 commit 7ebf967

File tree

6 files changed

+54
-40
lines changed

6 files changed

+54
-40
lines changed

src/coreclr/jit/compiler.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -7181,12 +7181,13 @@ class Compiler
71817181

71827182
bool isCompatibleMethodGDV(GenTreeCall* call, CORINFO_METHOD_HANDLE gdvTarget);
71837183

7184-
void addGuardedDevirtualizationCandidate(GenTreeCall* call,
7185-
CORINFO_METHOD_HANDLE methodHandle,
7186-
CORINFO_CLASS_HANDLE classHandle,
7187-
unsigned methodAttr,
7188-
unsigned classAttr,
7189-
unsigned likelihood);
7184+
void addGuardedDevirtualizationCandidate(GenTreeCall* call,
7185+
CORINFO_METHOD_HANDLE methodHandle,
7186+
CORINFO_CLASS_HANDLE classHandle,
7187+
CORINFO_CONTEXT_HANDLE contextHandle,
7188+
unsigned methodAttr,
7189+
unsigned classAttr,
7190+
unsigned likelihood);
71907191

71917192
int getGDVMaxTypeChecks()
71927193
{

src/coreclr/jit/fginline.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,8 @@ class SubstitutePlaceholdersAndDevirtualizeWalker : public GenTreeVisitor<Substi
475475
// info.
476476
}
477477

478-
m_compiler->impDevirtualizeCall(call, nullptr, &method, &methodFlags, &context, nullptr,
478+
CORINFO_CONTEXT_HANDLE contextInput = context;
479+
m_compiler->impDevirtualizeCall(call, nullptr, &method, &methodFlags, &contextInput, &context,
479480
isLateDevirtualization, explicitTailCall);
480481
m_madeChanges = true;
481482
}

src/coreclr/jit/importercalls.cpp

+23-12
Original file line numberDiff line numberDiff line change
@@ -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

src/coreclr/jit/indirectcalltransformer.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ class IndirectCallTransformer
862862

863863
JITDUMP("Direct call [%06u] in block " FMT_BB "\n", compiler->dspTreeID(call), block->bbNum);
864864

865-
CORINFO_METHOD_HANDLE methodHnd = call->gtCallMethHnd;
865+
CORINFO_METHOD_HANDLE methodHnd = inlineInfo->guardedMethodHandle;
866866
CORINFO_CONTEXT_HANDLE context = inlineInfo->exactContextHnd;
867867
if (clsHnd != NO_CLASS_HANDLE)
868868
{
@@ -872,7 +872,8 @@ class IndirectCallTransformer
872872
unsigned methodFlags = compiler->info.compCompHnd->getMethodAttribs(methodHnd);
873873
const bool isLateDevirtualization = true;
874874
const bool explicitTailCall = (call->AsCall()->gtCallMoreFlags & GTF_CALL_M_EXPLICIT_TAILCALL) != 0;
875-
compiler->impDevirtualizeCall(call, nullptr, &methodHnd, &methodFlags, &context, nullptr,
875+
CORINFO_CONTEXT_HANDLE contextInput = context;
876+
compiler->impDevirtualizeCall(call, nullptr, &methodHnd, &methodFlags, &contextInput, &context,
876877
isLateDevirtualization, explicitTailCall);
877878
}
878879
else

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

+19-13
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,10 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
12771277
}
12781278

12791279
MethodDesc decl = HandleToObject(info->virtualMethod);
1280+
1281+
// Transform from the unboxing thunk to the normal method
1282+
decl = decl.IsUnboxingThunk() ? decl.GetUnboxedMethod() : decl;
1283+
12801284
Debug.Assert(!decl.HasInstantiation);
12811285

12821286
if ((info->context != null) && decl.OwningType.IsInterface)
@@ -1369,7 +1373,6 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
13691373
#endif
13701374
);
13711375
}
1372-
info->resolvedTokenDevirtualizedUnboxedMethod = default(CORINFO_RESOLVED_TOKEN);
13731376
}
13741377
else
13751378
{
@@ -1382,26 +1385,29 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
13821385
, methodWithTokenImpl
13831386
#endif
13841387
);
1388+
}
13851389

1386-
if (unboxingStub)
1387-
{
1388-
info->resolvedTokenDevirtualizedUnboxedMethod = info->resolvedTokenDevirtualizedMethod;
1389-
info->resolvedTokenDevirtualizedUnboxedMethod.tokenContext = contextFromMethod(nonUnboxingImpl);
1390-
info->resolvedTokenDevirtualizedUnboxedMethod.hMethod = ObjectToHandle(nonUnboxingImpl);
1391-
}
1392-
else
1393-
{
1394-
info->resolvedTokenDevirtualizedUnboxedMethod = default(CORINFO_RESOLVED_TOKEN);
1395-
}
1390+
if (unboxingStub)
1391+
{
1392+
info->resolvedTokenDevirtualizedUnboxedMethod = info->resolvedTokenDevirtualizedMethod;
1393+
info->resolvedTokenDevirtualizedUnboxedMethod.tokenContext = contextFromMethod(nonUnboxingImpl);
1394+
info->resolvedTokenDevirtualizedUnboxedMethod.hMethod = ObjectToHandle(nonUnboxingImpl);
1395+
}
1396+
else
1397+
{
1398+
info->resolvedTokenDevirtualizedUnboxedMethod = default(CORINFO_RESOLVED_TOKEN);
13961399
}
13971400

13981401
#if READYTORUN
13991402
// Testing has not shown that concerns about virtual matching are significant
14001403
// Only generate verification for builds with the stress mode enabled
14011404
if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
14021405
{
1403-
ISymbolNode virtualResolutionNode = _compilation.SymbolNodeFactory.CheckVirtualFunctionOverride(methodWithTokenDecl, objType, methodWithTokenImpl);
1404-
AddPrecodeFixup(virtualResolutionNode);
1406+
if (!methodWithTokenDecl.Method.OwningType.IsValueType || !methodWithTokenImpl.Method.OwningType.IsValueType)
1407+
{
1408+
ISymbolNode virtualResolutionNode = _compilation.SymbolNodeFactory.CheckVirtualFunctionOverride(methodWithTokenDecl, objType, methodWithTokenImpl);
1409+
AddPrecodeFixup(virtualResolutionNode);
1410+
}
14051411
}
14061412
#endif
14071413
info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_SUCCESS;

src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -1015,12 +1015,6 @@ CorInfoInitClassResult MethodContext::repInitClass(CORINFO_FIELD_HANDLE field,
10151015
key.method = CastHandle(method);
10161016
key.context = CastHandle(context);
10171017

1018-
if ((InitClass == nullptr) || (InitClass->GetIndex(key) == -1))
1019-
{
1020-
// We could try additional inlines with stress modes, just reject them.
1021-
return CORINFO_INITCLASS_DONT_INLINE;
1022-
}
1023-
10241018
DWORD value = InitClass->Get(key);
10251019
DEBUG_REP(dmpInitClass(key, value));
10261020
CorInfoInitClassResult result = (CorInfoInitClassResult)value;

0 commit comments

Comments
 (0)