-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Updating the JIT to support marshaling blittable generics. #23899
Conversation
Still TODO:
|
Responded to feedback so far; added tests covering arrays, points, ref, and out. I'm going to be camping until Monday, but I'll see how far I can get this tonight. |
Can you make sure to add a test for a non-generic struct containing a field that has a type of an instantiated generic struct? |
CC. @CarolEidt. You might be interested in this from the perspective of the vector ABI support |
For the Will also need to figure out how to handle cases where a given platform doesn't quite support a given type. For example, ARM does not support |
You can gain some coverage for marshalling coreclr/tests/src/JIT/Stress/ABI/Program.cs Lines 486 to 500 in 10d49b5
Adding Vector64<T> would be fine too.
|
Rebased onto current head. |
You might need to add an explicit block for |
I'm guessing this is because |
Yep that's why. We actually probably just want to prohibit |
We should keep blocking Vector128 and similar cases for interop until this is fixed. |
I'll update to explicitly block these and |
Can you also ensure that |
Thank you for your contribution. As announced in dotnet/coreclr#27549 this repository will be moving to dotnet/runtime on November 13. If you would like to continue working on this PR after this date, the easiest way to move the change to dotnet/runtime is:
|
@tannergooding What are you thoughts for this PR with respect to repo consolidation? I am going to assume you would like this in prior to that happening. Please confirm so @jkoritzinsky and myself can prioritize reviewing this PR. |
@AaronRobinsonMSFT, I'm not particularly concerned either way. I just had some time to finally add some of the tests that were missing. If I happen to get all needed test coverage and CI passing, then I'm fine with it being reviewed and merged before the consolidation. Otherwise, I'm also perfectly comfortable shuffling these changes over into a new PR 😄 |
I looked at the product changes and they seem reasonable with no concerns from me. I want to peek a bit more at some of the tests themselves, but otherwise if the CI is green and coverage is what has been agreed upon I am signed off. Thanks for driving this work - much appreciated! |
I still need tests validating Ideally, I would also have tests covering (validating they don't work) generic COM types, generic classes with Right now I'm trying to validate I have the |
It looks like for ARM32 we target
Edit: Looks like GCC documents |
@CarolEidt, were you planning on having Just want to make sure I add the appropriate tests here and disallow it for the time being if necessary 😄 |
|
@jkotas, what would be the appropriate way to handle That is, as of C# 8 since Should that just be allowed and people are on their own or should we poison even pointers to In a somewhat similar vein, |
Unmanaged pointers to anything are fine with me. Do we prohibit any unmanaged pointers in interop today? I would not mind removing any restrictions if there are any. |
We prohibit unmanaged pointers to non-blittable types in parameters and return values. We've never been able to do so to structs because of the fact that the checking happened in the type loader and we'd end up with a seemingly cyclical type. For example, in the type below: unsafe struct D
{
D* ptr;
} We couldn't validate if In the parameter and return value case, the types are fully loaded so we can do the validation. If we want to allow marshalling unmanaged pointers to nonblittable "unmanaged" types as parameters and return values, I'd be ok with removing that restriction. |
It is not currently true, but I think that we should make it so. What I meant by "We can always ..." was "We should be able to always ..."
Right - I'd forgotten that the MMX registers are aliased to the FP stack registers :-( Although we could theoretically support that (we currently have to return float values on the stack for x86, it probably isn't worth it. |
I forgot to clear the MMX state for the Vector64 native code (which uses |
Ok, I should just need to add explicit tests covering (and ensuring they don't work) classes with I'm going to log an issue for enabling unmanaged pointers to non-blittable types (#23899 (comment)) and follow up with it in a subsequent PR. |
CC. @AaronRobinsonMSFT, @jkoritzinsky, @jkotas. I believe this should be ready for review now. I've done the following:
|
The vast majority of changes here are tests covering the same set of scenarios:
The types covered by the tests then touch:
These validate that various important ABI conventions are being correctly handled (such as HFA/HVA, two field structs that can be passed in register, etc). |
|| m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR64T)) | ||
|| m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR128T)) | ||
|| m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR256T)) | ||
#ifndef CROSSGEN_COMPILE |
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.
Why is this ifndef necessary? We try to avoid logic differences like this for crossgen.
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.
Vector<T>
is blocked from even being type loaded during crossgen (due to its variable size): https://github.com/dotnet/coreclr/blob/master/src/vm/methodtablebuilder.cpp#L1182
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.
Ok, make sense. I have not realized that this is to avoid failing here 100% of time during crossgen. Comment may be nice
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.
Is there a matching change to be done for this in crossgen2?
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.
I'm not sure. Looking at crossgen2, I don't see any specific handling of Vector<T>
and disallowing it as a type.
I did find a section for the FieldLayoutAlgorithm: https://github.com/dotnet/coreclr/blob/master/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs#L50
However, that field layout only supports Vector64/128/256<T>
: https://github.com/dotnet/coreclr/blob/master/src/tools/crossgen2/Common/Compiler/VectorFieldLayoutAlgorithm.cs
The only logic I can find for Vector<T>
is in the SystemVStructClassificator
where it doesn't treat it as an EightBytes struct: https://github.com/dotnet/coreclr/blob/master/src/tools/crossgen2/Common/JitInterface/SystemVStructClassificator.cs#L273
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.
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.
What is the easiest way to test Crossgen2 on an specific test?
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.
I've pushed up a commit which I believe handles this, but it's not been tested (and doesn't look to be covered by CI currently).
That's correct, the SVE ACLE types we have are incomplete, sizeless and definite.
Not by anything user-mode. While technically the kernel is allowed to change it, the expectation is that it won't do this after the process has started. You can have processes with different VLs on the same system though.
Yeah, "sizeless" of a specific type. So the way I saw it was that SVE also allows compiling code for a specific VL, in which case in ACLE you are then allowed to cast between the incomplete and a known complete type.
Ah, wait, I think I'm missing something here.. Is
Hmm perhaps... that said there are other ISAs other than SVE which have the same understanding as VL agnostic types. So I wouldn't necessarily say this type would need to be SVE specific. |
@TamarChristinaArm, I'ved forked the discussion off to: https://github.com/dotnet/coreclr/issues/27814 |
…ing in favor of fixing the text in IDS_EE_BADMARSHAL_GENERICS_RESTRICTION
Closing as this has been ported to dotnet/runtime repo. |
This resolves https://github.com/dotnet/coreclr/issues/1685