-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve JitDisasm for top-level statements, expose DumpJittedMethods in Release #74090
Conversation
…se DumpJittedMethods for Release
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsFor top-level statements (which are used by default when one creates console app via using System;
Foo();
void Foo() => Console.WriteLine("Foo"); Both of these:
didn't work as they had to be Also, expose
I didn't expose neither
|
Is this format compatible with |
Can we backport this to rc1? From my perspective, it meets the bar of addressing significant gaps in a new feature. The support for DOTNET_JitDisasm is awesome (it's literally the first thing I talk about in the .NET 7 performance post I'm writing), but its usability is hard because there's no good way to discover what can be written as the value for the variable, and there's no good way to simply express names that get mangled by the C# compiler (e.g. async methods, iterators, local methods, top-level statements main, generated main for async mains, etc.). On top of that, being able to see (without separate tools) what methods the JIT is compiling at a high-level is a stellar pedagogical tool, but just specifying * leads to way too much spew for it to be useful; having the one-line-per-compilation is a great for understanding what's being generated when. |
Just curious, but does it work to simply copy paste the name from DumpJittedMethods into JitDisasm to get the output in all cases? E.g. with generic instantiations, overloads... I feel like I often find that I cannot just copy the name directly. If @stephentoub is going to call these out in the blog post we should probably make sure this is seamless, or at least be aware of the cases that are broken. I think my preference would be to make the matching follow some very basic understandable rules, e.g. something like: the JitDisasm string is a space separated list of patterns. If any pattern matches the method has its disassembly printed. Patterns can contain wildcards and characters. The string matched against depends on the pattern, but starts out with just the method name:
I'm not sure how this matches the rules today. |
@jakobbotsch I've just checked - whatever
So, to match
Wildcards only work for methodName, className can be omitted or exactly match. @stephentoub do you have any preferences for better name instead of |
No strong preference. DOTNET_JitListMethods? DOTNET_JitListCompilations? DOTNET_JitDisasmSummary? |
@dotnet/jit-contrib PTAL, it's ready for review - also, any thoughts on a better name for end users? 🙂 |
src/coreclr/jit/jitconfigvalues.h
Outdated
@@ -257,6 +256,8 @@ CONFIG_INTEGER(EnableIncompleteISAClass, W("EnableIncompleteISAClass"), 0) // En | |||
CONFIG_METHODSET(JitDisasm, W("JitDisasm")) | |||
#endif // !defined(DEBUG) | |||
|
|||
CONFIG_INTEGER(DumpJittedMethods, W("DumpJittedMethods"), 0) // Prints all jitted methods to the console |
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.
This is going to be awesome
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.
As to naming, I prefer Stephen's suggestion DOTNET_JitDisasmSummary
Can you show some examples of the newest output format, especially including some OSR methods (e.g., from the ASP.NET collection)? |
Co-authored-by: Bruce Forstall <brucefo@microsoft.com>
Can you show an example with OSR in a Checked JIT? With JitStress enabled (in Checked)? Are you going to rename the option? |
Would also be nice to know if we're generating instrumented code and (perhaps) if we have access to PGO data -- and if so, what kind (at least for the root). |
{ | ||
// 's2' must start with 'nameLen' characters of 'name' | ||
if (strncmp(name, s2, nameLen) != 0) | ||
for (size_t srcPos = 0; srcPos <= srcSize - needleSize; srcPos++) |
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.
assert(srcSize >= needleSize)
?
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.
if needleSize is bigger it will just return "not found" because it actually can be bigger
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.
But in that case won't the srcSize - needleSize way bigger? You might just fast return "not found" in such cases.
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.
Guess this is still unaddressed.
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.
@kunalspathak sorry didn't notice your comment - I am not sure I understand, let's say
srcSize is 10
and needleSize is 20
, then srcSize - needleSize
is -10
so for-loop immediately exits and returns "not found" - am I wrong?
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 haven't looked in depth here, but srcSize - needleSize
can never be negative, since size_t
is unsigned.
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.
ah oops, it supposed to be ssize_t
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 haven't looked in depth here, but
srcSize - needleSize
can never be negative, sincesize_t
is unsigned.
^ That.
We should make sure the patchpoint IL offset shows up here. |
It looks like the code to do that is only under In fact, the "DEBUG" version, including |
Unified Debug and Release, initially I just didn't want to show users irrelevant data they won't ever need New Release output:
OSR offset is here. Also, renamed to |
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.
LGTM with one small request.
Andy said:
Would also be nice to know if we're generating instrumented code and (perhaps) if we have access to PGO data -- and if so, what kind (at least for the root).
Don't know if you want to address that, and if so, in this change or as a follow-up.
Co-authored-by: Bruce Forstall <brucefo@microsoft.com>
Added PGO on @AndyAyersMS's request, example:
e.g. 35 is both instrumented and optimized with PGO due to OSR |
Given that |
/backport to release/7.0-rc1 |
Started backporting to release/7.0-rc1: https://github.com/dotnet/runtime/actions/runs/2907852964 |
@EgorBo an error occurred while backporting to release/7.0-rc1, please check the run log for details! Error: @EgorBo is not a repo collaborator, backporting is not allowed. If you're a collaborator please make sure your dotnet team membership visibility is set to Public on https://github.com/orgs/dotnet/people?query=EgorBo |
/backport to release/7.0-rc1 |
Started backporting to release/7.0-rc1: https://github.com/dotnet/runtime/actions/runs/2907874603 |
@EgorBo backporting to release/7.0-rc1 failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Patch format detection failed.
Error: The process '/usr/bin/git' failed with exit code 128 Please backport manually! |
For top-level statements (which are used by default when one creates console app via
dotnet new console
) JitDisasm wasn't easy to use for e.g.:Both of these:
didn't work as they had to be
<Main>$
and<<Main>$>g__Foo|0_1()
but now they should work as is.Also, expose
DOTNET_DumpJittedMethods=1
in Release so users can ask JIT to list all methods it's jitting - closes #74084Example of its output:
I didn't expose neither
JitOrder
norJitFunctionTrace
as they look more low-level for end users, but happy to change that if you think it's worth exposing.