diff options
author | Jeremy Koritzinsky <jkoritzinsky@gmail.com> | 2019-01-09 10:06:25 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-09 10:06:25 -0800 |
commit | 03e2c029f7bbd36e06bcad3822b1dd3866772170 (patch) | |
tree | 4f5d82262e07650fdcb9e928b85132309ac1bc3e /src/vm/methodtable.cpp | |
parent | 7e0608fee5cacbf5bf7d0c3886e2fcb1a9d10754 (diff) | |
download | coreclr-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.cpp | 37 |
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); |