Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Marshal blittable structs via memcpy even if nested within non-blittable struct #20194

Merged
merged 22 commits into from
Oct 3, 2018
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d12b55b
Add regression test for dotnet/coreclr#18521.
jkoritzinsky Sep 28, 2018
a829208
Add custom marshaler for fixed buffers that acts as a scalar memory c…
jkoritzinsky Sep 28, 2018
20ddf24
Remove regression test. Moving it to a unit test in corefx.
jkoritzinsky Sep 28, 2018
cea1523
Move attribute class name into classnames.h
jkoritzinsky Sep 28, 2018
1393b09
Remove unreachable code left over from debugging.
jkoritzinsky Sep 28, 2018
412502b
Marshal fixed buffers by reusing the field marshaler of the single fi…
jkoritzinsky Oct 1, 2018
f9b6ae7
Remove now-dead code paths.
jkoritzinsky Oct 1, 2018
a04cbf1
Use initializers in FieldMarshaler_NestedValueClass constructor where…
jkoritzinsky Oct 1, 2018
e29416f
Clean up IsFixedBuffer implementation.
jkoritzinsky Oct 1, 2018
9f5d22e
Remove unused GC_PROTECTs.
jkoritzinsky Oct 1, 2018
aa6641c
Specifically check that the attribute exists, not just that there was…
jkoritzinsky Oct 1, 2018
b055b7a
Fix missing else statement.
jkoritzinsky Oct 2, 2018
f125ac8
Add asserts so we don't corrupt the heap.
jkoritzinsky Oct 2, 2018
496eef5
Add unit test for masked bug (incorrect native size of structure calc…
jkoritzinsky Oct 2, 2018
5236477
Don't use new behavior on non-blittable fixed buffers.
jkoritzinsky Oct 2, 2018
3e40bb0
Revert "Add unit test for masked bug (incorrect native size of struct…
jkoritzinsky Oct 2, 2018
ad0cb17
Use memcpy instead of field emulation.
jkoritzinsky Oct 2, 2018
b915e99
Remove unused forward-declared class.
jkoritzinsky Oct 2, 2018
89fddc5
Clean up code. Refactor one GetMethodTable call I missed.
jkoritzinsky Oct 2, 2018
ce4d8a6
Merge branch 'fixes/coreclr/18521' of https://github.com/jkoritzinsky…
jkoritzinsky Oct 2, 2018
9bc37ce
Remove now-unneeded custom attribute includes. More diff cleanup.
jkoritzinsky Oct 2, 2018
960f560
Remove unneeded FixedBufferAttribute define.
jkoritzinsky Oct 2, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 37 additions & 17 deletions src/vm/fieldmarshaler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2036,7 +2036,6 @@ VOID LayoutUpdateNative(LPVOID *ppProtectedManagedData, SIZE_T offsetbias, Metho
GCPROTECT_END();
}


VOID FmtClassUpdateNative(OBJECTREF *ppProtectedManagedData, BYTE *pNativeData, OBJECTREF *ppCleanupWorkListOnStack)
{
CONTRACTL
Expand Down Expand Up @@ -2115,7 +2114,7 @@ VOID FmtClassUpdateCLR(OBJECTREF *ppProtectedManagedData, BYTE *pNativeData)
// all of the native fields even if one or more of the conversions fail.
//=======================================================================
VOID LayoutUpdateCLR(LPVOID *ppProtectedManagedData, SIZE_T offsetbias, MethodTable *pMT, BYTE *pNativeData)
{
{
CONTRACTL
{
THROWS;
Expand All @@ -2128,19 +2127,19 @@ VOID LayoutUpdateCLR(LPVOID *ppProtectedManagedData, SIZE_T offsetbias, MethodTa
// Don't try to destroy/free native the structure on exception, we may not own it. If we do own it and
// are supposed to destroy/free it, we do it upstack (e.g. in a helper called from the marshaling stub).

FieldMarshaler* pFM = pMT->GetLayoutInfo()->GetFieldMarshalers();
UINT numReferenceFields = pMT->GetLayoutInfo()->GetNumCTMFields();
FieldMarshaler* pFM = pMT->GetLayoutInfo()->GetFieldMarshalers();
UINT numReferenceFields = pMT->GetLayoutInfo()->GetNumCTMFields();

struct _gc
{
OBJECTREF pCLRValue;
OBJECTREF pOldCLRValue;
} gc;

gc.pCLRValue = NULL;
gc.pCLRValue = NULL;
gc.pOldCLRValue = NULL;
LPVOID scalar = NULL;
LPVOID scalar = NULL;

GCPROTECT_BEGIN(gc)
GCPROTECT_BEGININTERIOR(scalar)
{
Expand Down Expand Up @@ -2873,12 +2872,21 @@ VOID FieldMarshaler_NestedValueClass::NestedValueClassUpdateNativeImpl(const VOI
}
CONTRACTL_END;

MethodTable* pMT = GetMethodTable();

// would be better to detect this at class load time (that have a nested value
// class with no layout) but don't have a way to know
if (! GetMethodTable()->GetLayoutInfo())
if (!pMT->GetLayoutInfo())
COMPlusThrow(kArgumentException, IDS_NOLAYOUT_IN_EMBEDDED_VALUECLASS);

LayoutUpdateNative((LPVOID*)ppProtectedCLR, startoffset, GetMethodTable(), (BYTE*)pNative, ppCleanupWorkListOnStack);
if (pMT->IsBlittable())
{
memcpyNoGCRefs(pNative, (BYTE*)(*ppProtectedCLR) + startoffset, pMT->GetNativeSize());
}
else
{
LayoutUpdateNative((LPVOID*)ppProtectedCLR, startoffset, pMT, (BYTE*)pNative, ppCleanupWorkListOnStack);
}
}


Expand All @@ -2898,17 +2906,24 @@ VOID FieldMarshaler_NestedValueClass::NestedValueClassUpdateCLRImpl(const VOID *
}
CONTRACTL_END;

MethodTable* pMT = GetMethodTable();

// would be better to detect this at class load time (that have a nested value
// class with no layout) but don't have a way to know
if (! GetMethodTable()->GetLayoutInfo())
if (!pMT->GetLayoutInfo())
COMPlusThrow(kArgumentException, IDS_NOLAYOUT_IN_EMBEDDED_VALUECLASS);

LayoutUpdateCLR( (LPVOID*)ppProtectedCLR,
startoffset,
GetMethodTable(),
(BYTE *)pNative);


if (pMT->IsBlittable())
{
memcpyNoGCRefs((BYTE*)(*ppProtectedCLR) + startoffset, pNative, pMT->GetNativeSize());
}
else
{
LayoutUpdateCLR((LPVOID*)ppProtectedCLR,
startoffset,
pMT,
(BYTE *)pNative);
}
}


Expand All @@ -2927,7 +2942,12 @@ VOID FieldMarshaler_NestedValueClass::DestroyNativeImpl(LPVOID pNativeValue) con
}
CONTRACTL_END;

LayoutDestroyNative(pNativeValue, GetMethodTable());
MethodTable* pMT = GetMethodTable();

if (!pMT->IsBlittable())
{
LayoutDestroyNative(pNativeValue, pMT);
}
}

#endif // CROSSGEN_COMPILE
Expand Down