-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8354520: IGV: dump contextual information #24724
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
8354520: IGV: dump contextual information #24724
Conversation
|
👋 Welcome back rcastanedalo! A progress list of the required criteria for merging this PR into |
|
@robcasloz This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 288 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
|
@robcasloz The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
mhaessig
left a comment
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.
Thank you for working on this and continually improving IGV!
I found two typos, but otherwise it looks good. I also tested printing to IGV from rr and the new features work as advertised.
Perhaps you could update the dump_bfs help with a comment about the new arguments?
|
|
||
| The JVM provides some entry functions to dump graphs from a debugger such as | ||
| `gdb` or `rr`, see the different variants of `igv_print` and `igv_append` in | ||
| `compile.cpp`. In combination with the IGV network interface, these functions |
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.
| `compile.cpp`. In combination with the IGV network interface, these functions | |
| [`compile.cpp`](src/hotspot/share/opto/compile.cpp). In combination with the | |
| IGV network interface, these functions |
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.
Thanks for the suggestion, but what is the value of adding such a link here?
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 often find them helpful to find the files a readme is referring to, so I tend to add them. But it's up to you whether you like them as well 🙂
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.
Fair enough, so the relative link will resolve correctly and point to the actual compile.cpp file on GitHub?
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 added the link now (commit 8193767d). Turns out GitHub would treat it, by default, as relative to the directory where the README.md file is placed, so I had to prefix it with / to make it relative to the root of the repo.
Co-authored-by: Manuel Hässig <manuel.hassig@oracle.com>
Thanks for trying out and reviewing, Manuel!
Done (commit d65ecdb), let me know if that works for you. I also made a minor correction to the IGV documentation (commit 86fdc67). |
dafedafe
left a comment
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.
Thanks a lot for adding this feature @robcasloz.
| Compile* C = Compile::current(); | ||
| C->init_igv(); | ||
| C->igv_print_graph_to_network("PrintBFS", _print_list); | ||
| C->igv_print_graph_to_network(nullptr, _print_list, _frame); |
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 suppose you removed "PrintBFS" to make the graph name be "Debug" like the other ones and make it easier to handle name and stack printing right?
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.
That's right.
Thanks for reviewing, Damon! |
eme64
left a comment
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.
Nice work @robcasloz !
I just left a few suggestions below, but I think they are basically all nits / optional :)
| IdealGraphPrinter* Compile::_debug_network_printer = nullptr; | ||
|
|
||
| // Called from debugger. Prints method to the default file with the default phase name. | ||
| // This works regardless of any Ideal Graph Visualizer flags set or not. |
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 works regardless of any Ideal Graph Visualizer flags set or not. | |
| // This works regardless of any Ideal Graph Visualizer flags set or not. | |
| // Use in debugger (gdb / rr): p igv_print($sp, $fp, $pc) |
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.
Done (commit 6b8e659).
| // the network flags for the Ideal Graph Visualizer, or to the default file depending on the 'network' argument. | ||
| // This works regardless of any Ideal Graph Visualizer flags set or not. | ||
| void igv_print(bool network) { | ||
| void igv_print(bool network, void* sp, void* fp, void* pc) { |
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.
| void igv_print(bool network, void* sp, void* fp, void* pc) { | |
| // Use in debugger (gdb / rr): p igv_print(true, $sp, $fp, $pc) | |
| void igv_print(bool network, void* sp, void* fp, void* pc) { |
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.
Done (commit 6b8e659).
src/hotspot/share/opto/compile.cpp
Outdated
| } | ||
| } | ||
|
|
||
| // Same as igv_print(bool network) above but with a specified phase name. |
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.
| // Same as igv_print(bool network) above but with a specified phase name. | |
| // Same as igv_print(bool network, void* sp, void* fp, void* pc) above but with a specified phase name. | |
| // Use in debugger (gdb / rr): p igv_print(true, "MyPhase", $sp, $fp, $pc) |
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.
Done (commit 6b8e659).
|
|
||
| // Called from debugger, especially when replaying a trace in which the program state cannot be altered like with rr replay. | ||
| // A method is appended to an existing default file with the default phase name. This means that igv_append() must follow | ||
| // an earlier igv_print(*) call which sets up the file. This works regardless of any Ideal Graph Visualizer flags set or not. |
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.
| // an earlier igv_print(*) call which sets up the file. This works regardless of any Ideal Graph Visualizer flags set or not. | |
| // an earlier igv_print(*) call which sets up the file. This works regardless of any Ideal Graph Visualizer flags set or not. | |
| // Use in debugger (gdb / rr): p igv_append($sp, $fp, $pc) |
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.
Done (commit 6b8e659).
src/hotspot/share/opto/compile.cpp
Outdated
| Compile::current()->igv_print_method_to_file(nullptr, true, &fr); | ||
| } | ||
|
|
||
| // Same as igv_append() above but with a specified phase name. |
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.
| // Same as igv_append() above but with a specified phase name. | |
| // Same as igv_append(void* sp, void* fp, void* pc) above but with a specified phase name. | |
| // Use in debugger (gdb / rr): p igv_append("MyPhase", $sp, $fp, $pc) |
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.
Done (commit 6b8e659).
| Thread* _current = Thread::current_or_null(); | ||
| int count = 0; | ||
| int frame = 0; | ||
| while (count++ < StackPrintLimit && fr.pc() != nullptr) { |
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.
Could this be formulated as a for loop?
| while (count++ < StackPrintLimit && fr.pc() != nullptr) { | |
| for (int count = 0; count < StackPrintLimit && fr.pc() != nullptr; count++) { |
Just an idea, totally optional.
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.
Done, thanks (commit 9cd331d).
|
|
||
| if (!_current_method || !_should_send_method || node == nullptr) return; | ||
|
|
||
| frame current = fr == nullptr ? os::current_frame() : *fr; |
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.
| frame current = fr == nullptr ? os::current_frame() : *fr; | |
| frame current_frame = fr == nullptr ? os::current_frame() : *fr; |
Just to make sure there is no confusion with _current_method.
Optional, up to you.
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: what is the implication of having the frame object on the stack, rather than a pointer to it?
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.
Well, never mind, I see it all over the runtime code base. Seems ok, though I'm a little uneasy about it. But not your problem, I guess ;)
| // Walk the native stack and print relevant C2 frames as IGV properties (if | ||
| // graph_name == nullptr) or the graph name based on the highest C2 frame (if | ||
| // graph_name != nullptr). | ||
| void print_stack(frame fr, outputStream* graph_name); |
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.
Are you passing this frame by value on purpose?
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 refactored this code in commit 6fa328e to pass the initial frame by reference.
src/hotspot/share/opto/node.cpp
Outdated
| const Node* _target; | ||
| const char* _options; | ||
| outputStream* _output; | ||
| frame* _frame; |
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.
Could this be const, like the other pointers?
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.
Done (commit 3c3108b), thanks.
| dump_bfs(max_distance, nullptr, nullptr); | ||
| } | ||
|
|
||
| // Call this from debugger, with stack handling register arguments for IGV dumps. |
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.
| // Call this from debugger, with stack handling register arguments for IGV dumps. | |
| // Call this from debugger, with stack handling register arguments for IGV dumps. | |
| // Example: p find_node(741)->dump_bfs(7, find_node(741), "c+A!", $sp, $fp, $pc) |
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.
Done (commit 6b8e659).
Thanks Emanuel, I addressed your comments and suggestions, including dumping of CPU features (as seen by C2, i.e. |
eme64
left a comment
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.
@robcasloz Amazing, thanks for the updates :)
|
Manuel, Damon, and Emanuel: thanks again for reviewing! |
|
/integrate |
|
Going to push as commit def907a.
Your commit was automatically rebased without conflicts. |
|
@robcasloz Pushed as commit def907a. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
This changeset extends the IGV graph dumps with additional properties that ease tracing the dumps back to the context in which they were produced. The changeset dumps, for every compilation, the following additional properties:
Additionally, the changeset produces and dumps the C2 stack trace from which each graph is dumped:
This should be particularly useful in an interactive context, where the user steps through C2 code using a debugger and dumps graphs at different points. To produce a stack trace in this context, the usual debugger-entry C2 functions (
igv_print,igv_append,Node::dump_bfs, ...) are extended with extra arguments to specify the stack handling registers (stack pointer, frame pointer, and program counter):The inconvenience of manually specifying the stack handling registers can be addressed by hiding them in debugger user-defined commands, e.g.:
Thanks to @TobiHartmann for providing useful feedback!
Testing
gdbandrron linux-x64.Progress
Issue
Reviewers
Reviewers without OpenJDK IDs
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/24724/head:pull/24724$ git checkout pull/24724Update a local copy of the PR:
$ git checkout pull/24724$ git pull https://git.openjdk.org/jdk.git pull/24724/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 24724View PR using the GUI difftool:
$ git pr show -t 24724Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/24724.diff
Using Webrev
Link to Webrev Comment