Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Jit: fix a few issues with single def local tracking #10633

Merged
merged 2 commits into from
Apr 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16379,6 +16379,14 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTreePtr tree, bool* isExact,
*isExact = false;
CORINFO_CLASS_HANDLE objClass = nullptr;

// Bail out if we're just importing and not generating code, since
// the jit uses TYP_REF for CORINFO_TYPE_VAR locals and args, but
// these may not be ref types.
if (compIsForImportOnly())
{
return objClass;
}

// Bail out if the tree is not a ref type.
var_types treeType = tree->TypeGet();
if (treeType != TYP_REF)
Expand Down
12 changes: 12 additions & 0 deletions src/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18515,6 +18515,18 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
CORINFO_CLASS_HANDLE baseClass = info.compCompHnd->getMethodClass(baseMethod);
const DWORD baseClassAttribs = info.compCompHnd->getClassAttribs(baseClass);

#if !defined(FEATURE_CORECLR)
// If base class is not beforefieldinit then devirtualizing may
// cause us to miss a base class init trigger. Spec says we don't
// need a trigger for ref class callvirts but desktop seems to
// have one anyways. So defer.
if ((baseClassAttribs & CORINFO_FLG_BEFOREFIELDINIT) == 0)
{
JITDUMP("\nimpDevirtualizeCall: base class has precise initialization, sorry\n");
return;
}
#endif // FEATURE_CORECLR

// Is the call an interface call?
const bool isInterface = (baseClassAttribs & CORINFO_FLG_INTERFACE) != 0;

Expand Down
34 changes: 31 additions & 3 deletions src/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2312,6 +2312,15 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool
void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
{
noway_assert(varNum < lvaCount);

// If we are just importing, we cannot reliably track local ref types,
// since the jit maps CORINFO_TYPE_VAR to TYP_REF.
if (compIsForImportOnly())
{
return;
}

// Else we should have a type handle.
assert(clsHnd != nullptr);

LclVarDsc* varDsc = &lvaTable[varNum];
Expand Down Expand Up @@ -2384,6 +2393,15 @@ void Compiler::lvaSetClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDL
void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
{
noway_assert(varNum < lvaCount);

// If we are just importing, we cannot reliably track local ref types,
// since the jit maps CORINFO_TYPE_VAR to TYP_REF.
if (compIsForImportOnly())
{
return;
}

// Else we should have a class handle to consider
assert(clsHnd != nullptr);

LclVarDsc* varDsc = &lvaTable[varNum];
Expand All @@ -2392,12 +2410,22 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool
// We should already have a class
assert(varDsc->lvClassHnd != nullptr);

// This should be the first and only update for this var
assert(!varDsc->lvClassInfoUpdated);

#if defined(DEBUG)

// In general we only expect one update per local var. However if
// a block is re-imported and that block has the only STLOC for
// the var, we may see multiple updates. All subsequent updates
// should agree on the type, since reimportation is triggered by
// type mismatches for things other than ref types.
if (varDsc->lvClassInfoUpdated)
{
assert(varDsc->lvClassHnd == clsHnd);
assert(varDsc->lvClassIsExact == isExact);
}

// This counts as an update, even if nothing changes.
varDsc->lvClassInfoUpdated = true;

#endif // defined(DEBUG)

// If previous type was exact, there is nothing to update. Would
Expand Down
Loading