summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>2019-01-09 10:06:25 -0800
committerGitHub <noreply@github.com>2019-01-09 10:06:25 -0800
commit03e2c029f7bbd36e06bcad3822b1dd3866772170 (patch)
tree4f5d82262e07650fdcb9e928b85132309ac1bc3e /src
parent7e0608fee5cacbf5bf7d0c3886e2fcb1a9d10754 (diff)
downloadcoreclr-03e2c029f7bbd36e06bcad3822b1dd3866772170.tar.gz
coreclr-03e2c029f7bbd36e06bcad3822b1dd3866772170.tar.bz2
coreclr-03e2c029f7bbd36e06bcad3822b1dd3866772170.zip
Remove extraneous eightbytes check for native structures and add tests. (#21590)
* Remove extraneous eightbytes check and add tests. * Interger -> Integer * Missed Helper.cs * Handle field sizes larger than 8 bytes in AssignClassifiedEightByteTypes * Move CoreFX test case into CoreCLR. Fix the SystemV eightbyte classifier to correctly classify the second eightbyte when a single field crosses the eightbyte boundary (such as an in-place array of three 4-byte enums). * Enable passing user defined structs in in-place arrays in a structure if SystemV ABI expects it. * Correctly handle a field spanning two full eightbytes. * Just directly assign 0 to accumulatedSizeForEightByte * Change multi-eightbyte field handling to be a loop as per PR feedback. * Remove extraneous whitespace.
Diffstat (limited to 'src')
-rw-r--r--src/vm/fieldmarshaler.h8
-rw-r--r--src/vm/methodtable.cpp37
2 files changed, 33 insertions, 12 deletions
diff --git a/src/vm/fieldmarshaler.h b/src/vm/fieldmarshaler.h
index 1f7ac88f44..24b10211c6 100644
--- a/src/vm/fieldmarshaler.h
+++ b/src/vm/fieldmarshaler.h
@@ -1029,8 +1029,12 @@ public:
{
LIMITED_METHOD_CONTRACT;
- MethodTable *pElementMT = m_arrayType.GetValue().AsArray()->GetArrayElementTypeHandle().GetMethodTable();
- return OleVariant::GetElementSizeForVarType(m_vt, pElementMT) * m_numElems;
+ return OleVariant::GetElementSizeForVarType(m_vt, GetElementMethodTable()) * m_numElems;
+ }
+
+ MethodTable* GetElementMethodTable() const
+ {
+ return GetElementTypeHandle().GetMethodTable();
}
TypeHandle GetElementTypeHandle() const
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index d7e98ffa48..e158436c21 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -2649,11 +2649,6 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin
unsigned normalizedFieldOffset = fieldOffset + startOffsetOfStruct;
unsigned int fieldNativeSize = pFieldMarshaler->NativeSize();
- if (fieldNativeSize > SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES)
- {
- // Pass on stack in this case.
- return false;
- }
_ASSERTE(fieldNativeSize != (unsigned int)-1);
@@ -2704,6 +2699,23 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin
case VT_R8:
fieldClassificationType = SystemVClassificationTypeSSE;
break;
+ case VT_RECORD:
+ {
+ MethodTable* pFieldMT = ((FieldMarshaler_FixedArray*)pFieldMarshaler)->GetElementMethodTable();
+
+ bool inEmbeddedStructPrev = helperPtr->inEmbeddedStruct;
+ helperPtr->inEmbeddedStruct = true;
+ bool structRet = pFieldMT->ClassifyEightBytesWithNativeLayout(helperPtr, nestingLevel + 1, normalizedFieldOffset, useNativeLayout);
+ helperPtr->inEmbeddedStruct = inEmbeddedStructPrev;
+
+ if (!structRet)
+ {
+ // If the nested struct says not to enregister, there's no need to continue analyzing at this level. Just return do not enregister.
+ return false;
+ }
+
+ continue;
+ }
case VT_DECIMAL:
case VT_DATE:
case VT_BSTR:
@@ -2714,7 +2726,6 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin
case VT_HRESULT:
case VT_CARRAY:
case VT_USERDEFINED:
- case VT_RECORD:
case VT_FILETIME:
case VT_BLOB:
case VT_STREAM:
@@ -3044,7 +3055,7 @@ void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHe
else
{
fieldSize = helperPtr->fieldSizes[ordinal];
- _ASSERTE(fieldSize > 0 && fieldSize <= SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES);
+ _ASSERTE(fieldSize > 0);
fieldClassificationType = helperPtr->fieldClassifications[ordinal];
_ASSERTE(fieldClassificationType != SystemVClassificationTypeMemory && fieldClassificationType != SystemVClassificationTypeUnknown);
@@ -3082,7 +3093,7 @@ void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHe
}
accumulatedSizeForEightByte += fieldSize;
- if (accumulatedSizeForEightByte == SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES)
+ while (accumulatedSizeForEightByte >= SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES)
{
// Save data for this eightbyte.
helperPtr->eightByteSizes[currentEightByte] = SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
@@ -3092,8 +3103,14 @@ void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHe
currentEightByte++;
_ASSERTE(currentEightByte <= CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS);
- currentEightByteOffset = offset + fieldSize;
- accumulatedSizeForEightByte = 0;
+ currentEightByteOffset += SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
+ accumulatedSizeForEightByte -= SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
+
+ // If a field is large enough to span multiple eightbytes, then set the eightbyte classification to the field's classification.
+ if (accumulatedSizeForEightByte > 0)
+ {
+ helperPtr->eightByteClassifications[currentEightByte] = fieldClassificationType;
+ }
}
_ASSERTE(accumulatedSizeForEightByte < SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES);