@@ -10638,23 +10638,48 @@ void Compiler::fgValueNumberTree(GenTree* tree)
10638
10638
{
10639
10639
assert (!isVolatile); // We don't expect both volatile and invariant
10640
10640
10641
- // Are we dereferencing the method table slot of some newly allocated object?
10642
- //
10643
- bool wasNewobj = false ;
10644
- if ((oper == GT_IND) && (addr->TypeGet () == TYP_REF) && (tree->TypeGet () == TYP_I_IMPL))
10641
+ bool returnsTypeHandle = false ;
10642
+ if ((oper == GT_IND) && addr->TypeIs (TYP_REF) && tree->TypeIs (TYP_I_IMPL))
10645
10643
{
10646
- VNFuncApp funcApp;
10647
- const bool addrIsVNFunc = vnStore->GetVNFunc (addrNvnp.GetLiberal (), &funcApp);
10648
-
10649
- if (addrIsVNFunc && (funcApp.m_func == VNF_JitNew) && addrNvnp.BothEqual ())
10644
+ // We try to access GC object's type, let's see if we know the exact type already
10645
+ // First, we're trying to do that via gtGetClassHandle.
10646
+ //
10647
+ bool isExact = false ;
10648
+ bool isNonNull = false ;
10649
+ CORINFO_CLASS_HANDLE handle = gtGetClassHandle (addr, &isExact, &isNonNull);
10650
+ if (isExact && (handle != NO_CLASS_HANDLE))
10650
10651
{
10651
- tree->gtVNPair =
10652
- vnStore->VNPWithExc (ValueNumPair (funcApp.m_args [0 ], funcApp.m_args [0 ]), addrXvnp);
10653
- wasNewobj = true ;
10652
+ JITDUMP (" IND(obj) is actually a class handle for %s\n " , eeGetClassName (handle));
10653
+ // Filter out all shared generic instantiations
10654
+ if ((info.compCompHnd ->getClassAttribs (handle) & CORINFO_FLG_SHAREDINST) == 0 )
10655
+ {
10656
+ void * pEmbedClsHnd;
10657
+ void * embedClsHnd = (void *)info.compCompHnd ->embedClassHandle (handle, &pEmbedClsHnd);
10658
+ if (pEmbedClsHnd == nullptr )
10659
+ {
10660
+ // Skip indirect handles for now since this path is mostly for PGO scenarios
10661
+ assert (embedClsHnd != nullptr );
10662
+ ValueNum handleVN = vnStore->VNForHandle ((ssize_t )embedClsHnd, GTF_ICON_CLASS_HDL);
10663
+ tree->gtVNPair = vnStore->VNPWithExc (ValueNumPair (handleVN, handleVN), addrXvnp);
10664
+ returnsTypeHandle = true ;
10665
+ }
10666
+ }
10667
+ }
10668
+ else
10669
+ {
10670
+ // Then, let's see if we can find JitNew at least
10671
+ VNFuncApp funcApp;
10672
+ const bool addrIsVNFunc = vnStore->GetVNFunc (addrNvnp.GetLiberal (), &funcApp);
10673
+ if (addrIsVNFunc && (funcApp.m_func == VNF_JitNew) && addrNvnp.BothEqual ())
10674
+ {
10675
+ tree->gtVNPair =
10676
+ vnStore->VNPWithExc (ValueNumPair (funcApp.m_args [0 ], funcApp.m_args [0 ]), addrXvnp);
10677
+ returnsTypeHandle = true ;
10678
+ }
10654
10679
}
10655
10680
}
10656
10681
10657
- if (!wasNewobj )
10682
+ if (!returnsTypeHandle )
10658
10683
{
10659
10684
// Indirections off of addresses for boxed statics represent bases for
10660
10685
// the address of the static itself. Here we will use "nullptr" for the
0 commit comments