summaryrefslogtreecommitdiff
path: root/src/vm/methodtable.cpp
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/vm/methodtable.cpp
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/vm/methodtable.cpp')
-rw-r--r--src/vm/methodtable.cpp37
1 files changed, 27 insertions, 10 deletions
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);