_ASSERTE(pMT->IsValueType());
+ // TODO: TypedReference should ideally be implemented as a by-ref-like struct containing a ByReference<T> field, in which
+ // case the check for g_TypedReferenceMT below would not be necessary
+ if (pMT == g_TypedReferenceMT)
+ {
+ gcPtrs[0] = TYPE_GC_BYREF;
+ gcPtrs[1] = TYPE_GC_NONE;
+ return 1;
+ }
+
ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS);
for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next())
{
if (pMT->IsByRefLike())
{
+ // TODO: TypedReference should ideally be implemented as a by-ref-like struct containing a ByReference<T> field, in
+ // which case the check for g_TypedReferenceMT below would not be necessary
if (pMT == g_TypedReferenceMT)
{
gcPtrs[0] = TYPE_GC_BYREF;
(*fn) (ppObj, sc, flags);
}
+void ReportByRefPointersFromByRefLikeObject(promote_func *fn, ScanContext *sc, PTR_MethodTable pMT, PTR_VOID pSrc)
+{
+ WRAPPER_NO_CONTRACT;
+
+ _ASSERTE(pMT->IsByRefLike());
+
+ // TODO: TypedReference should ideally be implemented as a by-ref-like struct containing a ByReference<T> field,
+ // in which case the check for g_TypedReferenceMT below would not be necessary
+ if (pMT == g_TypedReferenceMT || pMT->HasSameTypeDefAs(g_pByReferenceClass))
+ {
+ (*fn)(dac_cast<PTR_PTR_Object>(pSrc), sc, GC_CALL_INTERIOR);
+ return;
+ }
+
+ ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS);
+ for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next())
+ {
+ if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE)
+ {
+ continue;
+ }
+
+ // TODO: GetApproxFieldTypeHandleThrowing may throw. This is a potential stress problem for fragile NGen of non-CoreLib
+ // assemblies. It won\92t ever throw for CoreCLR with R2R. Figure out if anything needs to be done to deal with the
+ // exception.
+ PTR_MethodTable pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable();
+ if (!pFieldMT->IsByRefLike())
+ {
+ continue;
+ }
+
+ int fieldStartIndex = pFD->GetOffset() / sizeof(void *);
+ PTR_PTR_Object fieldRef = dac_cast<PTR_PTR_Object>(PTR_BYTE(pSrc) + fieldStartIndex);
+ ReportByRefPointersFromByRefLikeObject(fn, sc, pFieldMT, fieldRef);
+ }
+}
+
void ReportPointersFromValueType(promote_func *fn, ScanContext *sc, PTR_MethodTable pMT, PTR_VOID pSrc)
{
WRAPPER_NO_CONTRACT;
- // SPAN-TODO: GC reporting - https://github.com/dotnet/coreclr/issues/8517
+ if (pMT->IsByRefLike())
+ {
+ ReportByRefPointersFromByRefLikeObject(fn, sc, pMT, pSrc);
+ }
if (!pMT->ContainsPointers())
return;
void ReportPointersFromValueTypeArg(promote_func *fn, ScanContext *sc, PTR_MethodTable pMT, ArgDestination *pSrc)
{
WRAPPER_NO_CONTRACT;
-
- if (!pMT->ContainsPointers())
- return;
+
+ if(pMT->ContainsPointers())
+ {
#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
- if (pSrc->IsStructPassedInRegs())
+ if (pSrc->IsStructPassedInRegs())
+ {
+ pSrc->ReportPointersFromStructInRegisters(fn, sc, pMT->GetNumInstanceFieldBytes());
+ return;
+ }
+#endif // UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING
+ }
+ else if (!pMT->IsByRefLike())
{
- pSrc->ReportPointersFromStructInRegisters(fn, sc, pMT->GetNumInstanceFieldBytes());
return;
}
-#endif // UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING
ReportPointersFromValueType(fn, sc, pMT, pSrc->GetDestinationAddress());
}