diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 521aa32777b4be..1b3ad5d9a50fec 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3616,7 +3616,7 @@ class Compiler // Get a class handle from a helper call argument CORINFO_CLASS_HANDLE gtGetHelperArgClassHandle(GenTree* array); // Get the class handle for a field - CORINFO_CLASS_HANDLE gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsExact, bool* pIsNonNull); + CORINFO_CLASS_HANDLE gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, CORINFO_CLASS_HANDLE fieldOwnerCls, bool* pIsExact, bool* pIsNonNull); // Check if this tree is a typeof() bool gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle = nullptr); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 86caf8654cd9e5..f3f80b41eddc8c 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -18542,12 +18542,23 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if ((fldSeq != nullptr) && (fldSeq->GetOffset() == base->AsIntCon()->IconValue())) { CORINFO_FIELD_HANDLE fldHandle = base->AsIntCon()->gtFieldSeq->GetFieldHandle(); - objClass = gtGetFieldClassHandle(fldHandle, pIsExact, pIsNonNull); + objClass = gtGetFieldClassHandle(fldHandle, NO_CLASS_HANDLE, pIsExact, pIsNonNull); } } else if (base->OperIs(GT_FIELD_ADDR)) { - objClass = gtGetFieldClassHandle(base->AsFieldAddr()->gtFldHnd, pIsExact, pIsNonNull); + CORINFO_FIELD_HANDLE fldHandle = base->AsFieldAddr()->gtFldHnd; + CORINFO_CLASS_HANDLE fldOwnerCls = NO_CLASS_HANDLE; + + if (base->gtGetOp1() != nullptr) + { + // If it's an instance field, try to grab the class handle from the instance. + // we're going to use it as a hint for getFieldType + bool isExactObj = false; + bool isNonNullObj = false; + fldOwnerCls = gtGetClassHandle(base->gtGetOp1(), &isExactObj, &isNonNullObj); + } + objClass = gtGetFieldClassHandle(fldHandle, fldOwnerCls, pIsExact, pIsNonNull); } break; } @@ -18778,6 +18789,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetArrayElementClassHandle(GenTree* array) // // Arguments: // fieldHnd - field handle for field in question +// fieldOwnerCls - field's owner class handle, if known. // pIsExact - [OUT] true if type is known exactly // pIsNonNull - [OUT] true if field value is not null // @@ -18787,10 +18799,13 @@ CORINFO_CLASS_HANDLE Compiler::gtGetArrayElementClassHandle(GenTree* array) // // May examine runtime state of static field instances. -CORINFO_CLASS_HANDLE Compiler::gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsExact, bool* pIsNonNull) +CORINFO_CLASS_HANDLE Compiler::gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, + CORINFO_CLASS_HANDLE fieldOwnerCls, + bool* pIsExact, + bool* pIsNonNull) { CORINFO_CLASS_HANDLE fieldClass = nullptr; - CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &fieldClass); + CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &fieldClass, fieldOwnerCls); if (fieldCorType == CORINFO_TYPE_CLASS) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index ca1dd982e1cbb0..96f78f1d0e629f 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9150,6 +9150,12 @@ CorInfoType CEEInfo::getFieldType (CORINFO_FIELD_HANDLE fieldHnd, JIT_TO_EE_TRANSITION(); + PTR_MethodTable fldType = ((FieldDesc*)fieldHnd)->GetApproxEnclosingMethodTable(); + if ((owner != nullptr) && !TypeHandle(owner).AsMethodTable()->HasSameTypeDefAs(fldType)) + { + owner = nullptr; + } + result = getFieldTypeInternal(fieldHnd, pTypeHnd, owner); EE_TO_JIT_TRANSITION();