-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix for bugs related to clasifying System.TypedReference - issue #2854. #2860
Conversation
test OSX x64 Release Build and Test please |
@@ -276,12 +276,14 @@ enum SystemVClassificationType : unsigned __int8 | |||
SystemVClassificationTypeMemory = 3, | |||
SystemVClassificationTypeInteger = 4, | |||
SystemVClassificationTypeIntegerReference = 5, | |||
SystemVClassificationTypeSSE = 6, | |||
SystemVClassificationTypeIntegerByReference = 6, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor point - but I think these names confusing. It sounds like it's describing a integer being passed by reference. Also, "byref" is a specific term used in the CLI and so it would be more accurate to use that term. I think it should really be ByRefAsInteger (and the previous one "ReferenceAsInteger"), but at least change "ByReference" to "ByRef".
Comments addressed. PTAL. |
(structDesc.eightByteClassifications[slotCounter] == SystemVClassificationTypeIntegerReference))) || | ||
(doingFloat && structDesc.eightByteClassifications[slotCounter] == SystemVClassificationTypeSSE)) | ||
if ((!doingFloat && (structDesc.IsIntegralSlot(slotCounter))) || | ||
(doingFloat && (structDesc.IsSseSlot(slotCounter)))) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such an improvement in readability - thanks!
Aside from the genGet vs. getGet question above, LGTM |
// Internal flags - never returned outside of the classification implementation. | ||
|
||
// This value represents a very special type with two eightbytes. | ||
// First ByRef, secont Integer (platform int). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo - "second"
Suggestion: "First field is of type ByRef and second field an IntPtr"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@CarolEidt @sivarv PTAL |
@@ -1412,6 +1412,221 @@ void CodeGen::genCodeForBinary(GenTree* treeNode) | |||
genProduceReg(treeNode); | |||
} | |||
|
|||
// Deals with codegen for muti-register struct returns. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods lack function headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, could you add a line not to indicate what has changed? It is difficult to tell now that you have extracted this functionality into a separate method (a good thing to do, but also one of the reasons it is usually prudent to separate refactoring changes from functional changes).
@CarolEidt Good catch. Added function headers and added a comment in the PR description describing the genReturn related refactoring. |
void getStructReturnRegisters(var_types type0, | ||
var_types type1, | ||
regNumber* retRegPtr0, | ||
regNumber* retRegPtr1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: formatting of the above 3 params not aligned with the first one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@CarolEidt @sivarv PTAL the latest changes. |
Looks good. |
getEmitter()->emitIns_R_S(ins_Load(type1), emitTypeSize(type1), retReg1, lclVarPtr->gtLclNum, offset1); | ||
} | ||
|
||
// Nothing to do if the op1 of the return statement is a GT_CALL. The call already has the return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment here indicating that we are assuming that the registers will not be spilled or moved, and reference the newly created issue that will ensure correct codegen even in the presence of stress modes or other unforeseen changes.
LGTM if you add the comment I suggest to refer to issue #2966 |
It was a long standing assumption in the Jit that a field of a struct can never be of ByRef type. It turns out this assumption is not entirely holding. The System.TypedReference is a very special type that is a struct, defined to have two IntPtr fields. When the VM instantiates this type it changes the type of the first field to ByRef. This change closes a GC hole in the passing this struct by value on the stack. It adds support to the classification algorithm for ByRef references. It also uses the tree types for generating the code that places struct field on the stack by value for passin to a callee. The handling of GT_RETURN in the codegenxarch.cpp has been extracted as a separate routine - genReturn. In case of struct return (multi-register struct return or an implicit retBuf return, it delegates to the genStructReturn method. This is a refactoring as well as making sure that GT_RETFILT is handled properly - the return type of it is always bool or void for the last statement of a finally block. More feedback addressed.
@dotnet-bot OSX x64 Checked Build and Test |
@dotnet-bot test OSX x64 Checked Build and Test |
@dotnet-bot test Ubuntu x64 Checked Build and Test |
3 similar comments
@dotnet-bot test Ubuntu x64 Checked Build and Test |
@dotnet-bot test Ubuntu x64 Checked Build and Test |
@dotnet-bot test Ubuntu x64 Checked Build and Test |
@dotnet-bot test Ubuntu x64 Checked Build and Test |
Fix for bugs related to clasifying System.TypedReference - issue #2854.
It was a long standing assumption in the Jit that a field of a struct can
never be of ByRef type. It turns out this assumption is not entirely
holding.
The System.TypedReference is a very special type that is a struct, defined
to have two IntPtr fields. When the VM instantiates this type it changes
the type of the first field to ByRef.
This change closes a GC hole in the passing this struct by value on the
stack. It adds support to the classification algorithm for ByRef
references. It also uses the tree types for generating the code that
places struct field on the stack by value for passin to a callee.