@@ -2509,121 +2509,7 @@ bool MethodTable::ClassifyEightBytes(SystemVStructRegisterPassingHelperPtr helpe
2509
2509
_ASSERTE (helperPtr->currentUniqueOffsetField < SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT);
2510
2510
} // end per-field for loop
2511
2511
2512
- if (!helperPtr->inEmbeddedStruct )
2513
- {
2514
- _ASSERTE (nestingLevel == 0 );
2515
-
2516
- // We're at the top level of the recursion, and we're done looking at the fields.
2517
- // Now sort the fields by offset and set the output data.
2518
-
2519
- int sortedFieldOrder[SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT];
2520
- for (unsigned i = 0 ; i < SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT; i++)
2521
- {
2522
- sortedFieldOrder[i] = -1 ;
2523
- }
2524
-
2525
- for (unsigned i = 0 ; i < helperPtr->currentUniqueOffsetField ; i++)
2526
- {
2527
- _ASSERTE (helperPtr->fieldOffsets [i] < SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT);
2528
- _ASSERTE (sortedFieldOrder[helperPtr->fieldOffsets [i]] == -1 ); // we haven't seen this field offset yet.
2529
- sortedFieldOrder[helperPtr->fieldOffsets [i]] = i;
2530
- }
2531
-
2532
- // Set the layoutSizes (includes holes from alignment of the fields.)
2533
- int lastField = -1 ;
2534
- for (unsigned i = 0 ; i < SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT; i++)
2535
- {
2536
- int ordinal = sortedFieldOrder[i];
2537
- if (ordinal == -1 )
2538
- {
2539
- continue ;
2540
- }
2541
-
2542
- if (lastField == -1 )
2543
- {
2544
- lastField = ordinal;
2545
- continue ;
2546
- }
2547
-
2548
- helperPtr->fieldLayoutSizes [lastField] = helperPtr->fieldOffsets [ordinal] - helperPtr->fieldOffsets [lastField];
2549
-
2550
- lastField = ordinal;
2551
- }
2552
- // Now the last field
2553
- _ASSERTE (lastField != -1 ); // if lastField==-1, then the struct has no fields!
2554
- helperPtr->fieldLayoutSizes [lastField] = helperPtr->structSize - helperPtr->fieldOffsets [lastField];
2555
-
2556
- // Calculate the eightbytes and their types.
2557
- unsigned int accumulatedSizeForEightByte = 0 ;
2558
- unsigned int lastEightByteOffset = 0 ;
2559
- unsigned int currentEightByte = 0 ;
2560
-
2561
- for (unsigned i = 0 ; i < SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT; i++)
2562
- {
2563
- int ordinal = sortedFieldOrder[i];
2564
- if (ordinal == -1 )
2565
- {
2566
- continue ;
2567
- }
2568
-
2569
- if ((accumulatedSizeForEightByte + helperPtr->fieldLayoutSizes [ordinal]) > SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES)
2570
- {
2571
- // Save data for this eightbyte.
2572
- helperPtr->eightByteSizes [currentEightByte] = accumulatedSizeForEightByte;
2573
- helperPtr->eightByteOffsets [currentEightByte] = lastEightByteOffset;
2574
-
2575
- // Set up for next eightbyte.
2576
- currentEightByte++;
2577
- _ASSERTE (currentEightByte < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS);
2578
-
2579
- lastEightByteOffset = helperPtr->fieldOffsets [ordinal];
2580
- accumulatedSizeForEightByte = 0 ;
2581
- }
2582
-
2583
- accumulatedSizeForEightByte += helperPtr->fieldLayoutSizes [ordinal];
2584
-
2585
- _ASSERTE (helperPtr->fieldClassifications [ordinal] != SystemVClassificationTypeMemory);
2586
-
2587
- if (helperPtr->eightByteClassifications [currentEightByte] == helperPtr->fieldClassifications [ordinal])
2588
- {
2589
- // Do nothing. The eight-byte is already classified.
2590
- }
2591
- else if (helperPtr->eightByteClassifications [currentEightByte] == SystemVClassificationTypeNoClass)
2592
- {
2593
- helperPtr->eightByteClassifications [currentEightByte] = helperPtr->fieldClassifications [ordinal];
2594
- }
2595
- else if ((helperPtr->eightByteClassifications [currentEightByte] == SystemVClassificationTypeInteger) ||
2596
- (helperPtr->fieldClassifications [ordinal] == SystemVClassificationTypeInteger))
2597
- {
2598
- _ASSERTE (helperPtr->fieldClassifications [ordinal] != SystemVClassificationTypeIntegerReference);
2599
- helperPtr->eightByteClassifications [currentEightByte] = SystemVClassificationTypeInteger;
2600
- }
2601
- else if ((helperPtr->eightByteClassifications [currentEightByte] == SystemVClassificationTypeIntegerReference) ||
2602
- (helperPtr->fieldClassifications [ordinal] == SystemVClassificationTypeIntegerReference))
2603
- {
2604
- helperPtr->eightByteClassifications [currentEightByte] = SystemVClassificationTypeIntegerReference;
2605
- }
2606
- else
2607
- {
2608
- helperPtr->eightByteClassifications [currentEightByte] = SystemVClassificationTypeSSE;
2609
- }
2610
- }
2611
-
2612
- helperPtr->eightByteCount = currentEightByte + 1 ;
2613
- helperPtr->eightByteSizes [currentEightByte] = accumulatedSizeForEightByte;
2614
- helperPtr->eightByteOffsets [currentEightByte] = lastEightByteOffset;
2615
- _ASSERTE (helperPtr->eightByteCount <= CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS);
2616
-
2617
- #ifdef _DEBUG
2618
- LOG ((LF_JIT, LL_EVERYTHING, " ----\n " ));
2619
- LOG ((LF_JIT, LL_EVERYTHING, " **** Number EightBytes: %d\n " , helperPtr->eightByteCount ));
2620
- for (unsigned i = 0 ; i < helperPtr->eightByteCount ; i++)
2621
- {
2622
- LOG ((LF_JIT, LL_EVERYTHING, " **** eightByte %d -- classType: %s, eightByteOffset: %d, eightByteSize: %d\n " ,
2623
- i, GetSystemVClassificationTypeName (helperPtr->eightByteClassifications [i]), helperPtr->eightByteOffsets [i], helperPtr->eightByteSizes [i]));
2624
- }
2625
- #endif // _DEBUG
2626
- }
2512
+ AssignClassifiedEightByteTypes (helperPtr, nestingLevel);
2627
2513
2628
2514
return true ;
2629
2515
}
@@ -3066,6 +2952,15 @@ bool MethodTable::ClassifyEightBytesForNativeStruct(SystemVStructRegisterPassing
3066
2952
3067
2953
} // end per-field for loop
3068
2954
2955
+ AssignClassifiedEightByteTypes (helperPtr, nestingLevel);
2956
+
2957
+ return true ;
2958
+ #endif // DACCESS_COMPILE
2959
+ }
2960
+
2961
+ // Assigns the classification types to the array with eightbyte types.
2962
+ void MethodTable::AssignClassifiedEightByteTypes (SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel)
2963
+ {
3069
2964
if (!helperPtr->inEmbeddedStruct )
3070
2965
{
3071
2966
_ASSERTE (nestingLevel == 0 );
@@ -3108,7 +3003,14 @@ bool MethodTable::ClassifyEightBytesForNativeStruct(SystemVStructRegisterPassing
3108
3003
}
3109
3004
// Now the last field
3110
3005
_ASSERTE (lastField != -1 ); // if lastField==-1, then the struct has no fields!
3111
- helperPtr->fieldLayoutSizes [lastField] = helperPtr->structSize - helperPtr->fieldOffsets [lastField];
3006
+
3007
+ // A field size cannot be bigger than the size of an eightbyte.
3008
+ // There are cases where for the native layout of a struct the VM allocates 16
3009
+ // bytes space, but the struct has one eight-byte field.
3010
+ // This field is of classification type INTEGER or INTEGERREFERENCE.
3011
+ // Make sure the field layout size does not extend beyound an eightbyte.
3012
+ _ASSERTE (helperPtr->fieldSizes [lastField] <= SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES);
3013
+ helperPtr->fieldLayoutSizes [lastField] = min (helperPtr->structSize - helperPtr->fieldOffsets [lastField], SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES);
3112
3014
3113
3015
// Calculate the eightbytes and their types.
3114
3016
unsigned int accumulatedSizeForEightByte = 0 ;
@@ -3123,6 +3025,8 @@ bool MethodTable::ClassifyEightBytesForNativeStruct(SystemVStructRegisterPassing
3123
3025
continue ;
3124
3026
}
3125
3027
3028
+ _ASSERTE (helperPtr->fieldLayoutSizes [ordinal] <= SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES);
3029
+
3126
3030
if ((accumulatedSizeForEightByte + helperPtr->fieldLayoutSizes [ordinal]) > SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES)
3127
3031
{
3128
3032
// Save data for this eightbyte.
@@ -3134,10 +3038,12 @@ bool MethodTable::ClassifyEightBytesForNativeStruct(SystemVStructRegisterPassing
3134
3038
_ASSERTE (currentEightByte < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS);
3135
3039
3136
3040
lastEightByteOffset = helperPtr->fieldOffsets [ordinal];
3137
- accumulatedSizeForEightByte = 0 ;
3041
+ accumulatedSizeForEightByte = (accumulatedSizeForEightByte + helperPtr->fieldLayoutSizes [ordinal]) - SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
3042
+ }
3043
+ else
3044
+ {
3045
+ accumulatedSizeForEightByte += helperPtr->fieldLayoutSizes [ordinal];
3138
3046
}
3139
-
3140
- accumulatedSizeForEightByte += helperPtr->fieldLayoutSizes [ordinal];
3141
3047
3142
3048
_ASSERTE (helperPtr->fieldClassifications [ordinal] != SystemVClassificationTypeMemory);
3143
3049
@@ -3181,9 +3087,6 @@ bool MethodTable::ClassifyEightBytesForNativeStruct(SystemVStructRegisterPassing
3181
3087
}
3182
3088
#endif // _DEBUG
3183
3089
}
3184
-
3185
- return true ;
3186
- #endif // DACCESS_COMPILE
3187
3090
}
3188
3091
3189
3092
#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
0 commit comments