CORINFO_CLASS_HANDLE gtGetStructHandle(GenTree* tree);
// Get the handle for a ref type.
CORINFO_CLASS_HANDLE gtGetClassHandle(GenTree* tree, bool* isExact, bool* isNonNull);
+ // Get the element handle for an array of ref type.
+ CORINFO_CLASS_HANDLE gtGetArrayElementClassHandle(GenTree* array);
//-------------------------------------------------------------------------
// Functions to display the trees
case GT_IND:
{
- // indir(addr(lcl)) --> lcl
- //
- // This comes up during constrained callvirt on ref types.
GenTreeIndir* indir = obj->AsIndir();
+
if (indir->HasBase() && !indir->HasIndex())
{
+ // indir(addr(lcl)) --> lcl
+ //
+ // This comes up during constrained callvirt on ref types.
+
GenTree* base = indir->Base();
GenTreeLclVarCommon* lcl = base->IsLocalAddrExpr();
objClass = lvaTable[objLcl].lvClassHnd;
*isExact = lvaTable[objLcl].lvClassIsExact;
}
+ else if (base->OperGet() == GT_ARR_ELEM)
+ {
+ // indir(arr_elem(...)) -> array element type
+
+ GenTree* array = base->AsArrElem()->gtArrObj;
+
+ objClass = gtGetArrayElementClassHandle(array);
+ *isExact = false;
+ *isNonNull = false;
+ }
}
break;
}
break;
}
+ case GT_INDEX:
+ {
+ GenTree* array = obj->AsIndex()->Arr();
+
+ objClass = gtGetArrayElementClassHandle(array);
+ *isExact = false;
+ *isNonNull = false;
+ break;
+ }
+
default:
{
break;
return objClass;
}
+//------------------------------------------------------------------------
+// gtGetArrayElementClassHandle: find class handle for elements of an array
+// of ref types
+//
+// Arguments:
+// array -- array to find handle for
+//
+// Return Value:
+// nullptr if element class handle is unknown, otherwise the class handle.
+
+CORINFO_CLASS_HANDLE Compiler::gtGetArrayElementClassHandle(GenTree* array)
+{
+ bool isArrayExact = false;
+ bool isArrayNonNull = false;
+ CORINFO_CLASS_HANDLE arrayClassHnd = gtGetClassHandle(array, &isArrayExact, &isArrayNonNull);
+
+ if (arrayClassHnd != nullptr)
+ {
+ // We know the class of the reference
+ DWORD attribs = info.compCompHnd->getClassAttribs(arrayClassHnd);
+
+ if ((attribs & CORINFO_FLG_ARRAY) != 0)
+ {
+ // We know for sure it is an array
+ CORINFO_CLASS_HANDLE elemClassHnd = nullptr;
+ CorInfoType arrayElemType = info.compCompHnd->getChildType(arrayClassHnd, &elemClassHnd);
+
+ if (arrayElemType == CORINFO_TYPE_CLASS)
+ {
+ // We know it is an array of ref types
+ return elemClassHnd;
+ }
+ }
+ }
+
+ return nullptr;
+}
+
void GenTree::ParseArrayAddress(
Compiler* comp, ArrayInfo* arrayInfo, GenTree** pArr, ValueNum* pInxVN, FieldSeqNode** pFldSeq)
{