diff options
author | Koundinya Veluri <kouvel@users.noreply.github.com> | 2017-11-06 14:28:41 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-06 14:28:41 -0800 |
commit | 1a67e84aca889cf94c716a7847cfe0b4d1ee62d6 (patch) | |
tree | ee24ebe93ec1ea69c456b729c495f1ead37394de /src/vm/object.inl | |
parent | aee95b5490f55512635f8f87c21e54e164fb9a2f (diff) | |
download | coreclr-1a67e84aca889cf94c716a7847cfe0b4d1ee62d6.tar.gz coreclr-1a67e84aca889cf94c716a7847cfe0b4d1ee62d6.tar.bz2 coreclr-1a67e84aca889cf94c716a7847cfe0b4d1ee62d6.zip |
Fix GC reporting for slow tail call arguments of type `Span<T>` (#14826)
Fix GC reporting for slow tail call arguments of type `Span<T>`
Fixes https://github.com/dotnet/coreclr/issues/9032:
- Refactored by-ref-like method table walking to find offsets of by-ref pointers in siginfo.hpp/cpp
- Reused that for appending GC layout when creating the copy-args helper for a slow tail call
Diffstat (limited to 'src/vm/object.inl')
-rw-r--r-- | src/vm/object.inl | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/vm/object.inl b/src/vm/object.inl index 5dc3d6d116..495f7bff71 100644 --- a/src/vm/object.inl +++ b/src/vm/object.inl @@ -325,4 +325,41 @@ inline TypeHandle Object::GetGCSafeTypeHandle() const return TypeHandle(pMT); } +template<class F> +inline void FindByRefPointerOffsetsInByRefLikeObject(PTR_MethodTable pMT, SIZE_T baseOffset, const F processPointerOffset) +{ + WRAPPER_NO_CONTRACT; + _ASSERTE(pMT != nullptr); + _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)) + { + processPointerOffset(baseOffset); + 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't 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; + } + + SIZE_T fieldStartIndex = pFD->GetOffset() / sizeof(void *); + FindByRefPointerOffsetsInByRefLikeObject(pFieldMT, baseOffset + fieldStartIndex, processPointerOffset); + } +} + #endif // _OBJECT_INL_ |