From ddb38243566f4a98f3a53487b1557f1810cfc9b7 Mon Sep 17 00:00:00 2001 From: petris Date: Sat, 1 Jul 2023 00:41:44 +0200 Subject: [PATCH] Improve updating classes for generics --- src/coreclr/jit/lclvars.cpp | 26 +++++++++---------- .../tools/Common/JitInterface/CorInfoImpl.cs | 5 ++-- src/coreclr/vm/jitinterface.cpp | 5 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index a1cfe959fd7b6..5306045d0b8d8 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3177,37 +3177,35 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool assert(varDsc->lvSingleDef); // Now see if we should update. - // + // New information may not always be "better" so do some // simple analysis to decide if the update is worthwhile. const bool isNewClass = (clsHnd != varDsc->lvClassHnd); bool shouldUpdate = false; - // Are we attempting to update the class? Only check this when we have - // an new type and the existing class is inexact... we should not be - // updating exact classes. - if (!varDsc->lvClassIsExact && isNewClass) + // Are we attempting to update exactness? + if (isExact && !varDsc->lvClassIsExact) { - shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); + shouldUpdate = true; } - // Else are we attempting to update exactness? - else if (isExact && !varDsc->lvClassIsExact && !isNewClass) + // Are we attempting to update the class? + else if (isNewClass) { - shouldUpdate = true; + shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); } -#if DEBUG - if (isNewClass || (isExact != varDsc->lvClassIsExact)) + if (shouldUpdate) { +#if DEBUG JITDUMP("\nlvaUpdateClass:%s Updating class for V%02u", shouldUpdate ? "" : " NOT", varNum); JITDUMP(" from (%p) %s%s", dspPtr(varDsc->lvClassHnd), eeGetClassName(varDsc->lvClassHnd), varDsc->lvClassIsExact ? " [exact]" : ""); JITDUMP(" to (%p) %s%s\n", dspPtr(clsHnd), eeGetClassName(clsHnd), isExact ? " [exact]" : ""); - } #endif // DEBUG - if (shouldUpdate) - { + assert(!varDsc->lvClassIsExact || + ((info.compCompHnd->getClassAttribs(varDsc->lvClassHnd) & CORINFO_FLG_SHAREDINST) != 0)); + varDsc->lvClassHnd = clsHnd; varDsc->lvClassIsExact = isExact; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 579e933d4e2f4..f650fea72a1bb 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2818,8 +2818,9 @@ private bool isMoreSpecificType(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUC if (isType1CanonSubtype != isType2CanonSubtype) { // Only one of type1 and type2 is shared. - // type2 is more specific if type1 is the shared type. - return isType1CanonSubtype; + // type2 is more specific if type1 can't be assigned there. + return isType1CanonSubtype && !type1.CanCastTo(type2) || + isType2CanonSubtype && type2.CanCastTo(type1); } // Otherwise both types are either shared or not shared. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index bd8640ac47c97..8829bcb6105aa 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4458,8 +4458,9 @@ static BOOL isMoreSpecificTypeHelper( if (isHnd1CanonSubtype != isHnd2CanonSubtype) { // Only one of hnd1 and hnd2 is shared. - // hdn2 is more specific if hnd1 is the shared type. - return isHnd1CanonSubtype; + // hdn2 is more specific if hnd1 can't be assigned there. + return (isHnd1CanonSubtype && !hnd1.CanCastTo(hnd2)) || + (isHnd2CanonSubtype && hnd2.CanCastTo(hnd1)); } // Otherwise both types are either shared or not shared.