Skip to content

Fix missing case for function pointer signatures in Crossgen2 - #73341

Merged
trylek merged 2 commits into
dotnet:mainfrom
trylek:72822
Aug 4, 2022
Merged

Fix missing case for function pointer signatures in Crossgen2#73341
trylek merged 2 commits into
dotnet:mainfrom
trylek:72822

Conversation

@trylek

@trylek trylek commented Aug 3, 2022

Copy link
Copy Markdown
Member

As Andy Ayers conjectured in the issue #72822 and I confirmed,
Crossgen2 signature emitter was missing the code path for
emitting function pointer signatures. This change fixes this
deficiency. The change also removes the issues.targets exclusion
of the affected test that Andy originally merged in to mitigate
the issue.

Thanks

Tomas

P.S. Even though MethodSignatureFlags more or less corresponds
to CoreCLR runtime calling convention, I have ignored this fact
and implemented an explicit conversion as I find it cleaner, please
let me know if you think otherwise. I would also appreciate
double-checking of the logic around Static vs. HASTHIS as I'm not
completely sure about the exact interpretation of this runtime flag.

/cc @dotnet/crossgen-contrib

Fixes: #72822

As Andy Ayers suggested in the issue dotnet#72822 and I confirmed,
Crossgen2 signature emitter was missing the code path for
emitting function pointer signatures. This change fixes this
deficiency. The change also removes the issues.targets exclusion
of the affected test that Andy originally merged in to mitigate
the issue.

Thanks

Tomas

if ((type.Signature.Flags & MethodSignatureFlags.Static) == 0)
{
callingConvention |= CorCallingConvention.IMAGE_CEE_CS_CALLCONV_HASTHIS | CorCallingConvention.IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS right here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's exactly what I'm trying to get my head around. I believe that ECMA managed method signatures do include the this pointer so I would assume it's explicit but I may be misunderstanding the purpose of the flag, it's not used very broadly in the CoreCLR native runtime.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MethodSignature initialization only uses HasThis to initialize the Static bit:

if (!header.IsInstance)
flags |= MethodSignatureFlags.Static;

so the reverse should do the same.

If we need to preserve HasExplicitThis too (I do not think we need to), we would need to store it in MethodSignature.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on your clarification I have removed the ExplicitThis flag when emitting the non-static function pointer signatures.

@jkotas jkotas Aug 4, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not sure about the ExplicitThis. I have looked into it some more and I think we should probably store it on MethodSignature when we are initializing it from Ecma metadata, store it here; and also send it to the JIT so that the JIT can do the right thing with it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have number of IL tests that exercise explicit this (look for "explicit instance" in *.il under tests). I am surprised that none of them fails.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, yes, we should handle explicitthis, although fixing all the places that work with that may be beyond the scope of what we should try to fix with this PR. I think it will likely be a fairly large fix to a bunch of places unrelated to the general thrust of the code written here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created a .NET 8 tracking issue for this task, #73407.

Comment thread src/coreclr/tools/Common/Internal/Runtime/CorConstants.cs Outdated
@jkotas

jkotas commented Aug 4, 2022

Copy link
Copy Markdown
Member

I have ignored this fact
and implemented an explicit conversion as I find it cleaner,

FWIW, the type system takes the casting shortcut:

// Verify that it is safe to convert CallingConvention to MethodSignatureFlags via a simple cast
Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)SignatureCallingConvention.CDecl);
Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)SignatureCallingConvention.StdCall);
Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)SignatureCallingConvention.ThisCall);
Debug.Assert((int)MethodSignatureFlags.CallingConventionVarargs == (int)SignatureCallingConvention.VarArgs);
Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConvention == (int)SignatureCallingConvention.Unmanaged);

I have reverted the additions to CorConstants and modified the
code to use the constants in System.Reflection.Metadata. I have
removed the flag translation based on Jan's confirmation that
the calling convention part of MethodSignatureFlags is indeed
kept in sync with the CoreCLR native runtime calling conventions
and I dropped the explicit this flag.

Thanks

Tomas

@davidwrighton davidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should probably fix the explicit this problem, but I'd like to see such a fix done as part of fixing explicit this throughout our product, not just in this situation.

@trylek

trylek commented Aug 4, 2022

Copy link
Copy Markdown
Member Author

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@trylek
trylek merged commit fda46be into dotnet:main Aug 4, 2022
@trylek
trylek deleted the 72822 branch August 4, 2022 23:03
@ghost ghost locked as resolved and limited conversation to collaborators Sep 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test failure JIT\\opt\\ValueNumbering\\TypeTestFolding\\TypeTestFolding.cmd

3 participants