Interleave GC Info with assembly#42552
Conversation
Output GC info delats *after* the instruction (or label) that changes it. Add `COMPlus_JitDisasmWithGC` option to turn on the interleaving with assembly. Fix dotnet#41647
|
@dotnet/jit-contrib PTAL |
|
Output is basically what I described here. The info is printed after the impacting instruction, and multiple changes (variables or registers) are combined in a single line of output. |
|
ping @dotnet/jit-contrib |
sandreenko
left a comment
There was a problem hiding this comment.
LGTM, a few small questions/comments
| { | ||
| GCtype gcType = (val & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF; | ||
| emitGCvarLiveUpd(offs, INT_MAX, gcType, addr); | ||
| emitGCvarLiveUpd(offs, INT_MAX, gcType, addr DEBUG_ARG(num)); |
There was a problem hiding this comment.
Thoughts: Was adding INT_MAX as a special value (that means it is a tracked variable, do not check) a TP optimization? Maybe we can revert it and always pass varNum or add an additional argument isTracked (default == false)?
There was a problem hiding this comment.
This is pre-existing. I spent just a little time trying to understand why it's doing this, but the logic is not entirely clear. It doesn't seem to be a TP optimization, but I hesitate to change this as part of what's intended to be a purely dump-related PR.
src/coreclr/src/jit/emit.cpp
Outdated
| { | ||
| emitGCvarLiveSet(offs, gcType, addr, disp); | ||
| #ifdef DEBUG | ||
| if ((EMIT_GC_VERBOSE || emitComp->opts.disasmWithGC) && ((unsigned)actualVarNum < emitComp->lvaCount) && |
There was a problem hiding this comment.
(unsigned)actualVarNum is already unsigned, is not it?
There was a problem hiding this comment.
Ah yes, thanks. I had originally attempted to use varNum (which is declared as int) before realizing that INT_MAX is being passed in some cases where it's an actual lclVar.
| } | ||
|
|
||
| //------------------------------------------------------------------------ | ||
| // emitDispGCVarDelta: Print a delta for GC variables |
There was a problem hiding this comment.
Thanks, this was for an earlier version, will fix.
| #else | ||
| bool isPinned = (desc->vpdVarNum & pinned_OFFSET_FLAG) != 0; | ||
|
|
||
| printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isPinned ? "pinned" : "", |
There was a problem hiding this comment.
Question: do you think that "pinned" information was not useful in the past?
There was a problem hiding this comment.
I'm not sure as to how useful it was, but since that information is printed in the table of locals, it didn't seem necessary to repeat it in the dumps.
src/coreclr/src/jit/emit.cpp
Outdated
| // Interleaved GC info dumping. | ||
| // We'll attempt to line this up with the opcode, which indented differently for | ||
| // diffable and non-diffable dumps. | ||
| // This is approximate, and is better tuned for disassembly than for jitudmps. |
There was a problem hiding this comment.
Thanks - will fix.
src/coreclr/src/jit/emit.cpp
Outdated
|
|
||
| // We dump less information when we're only interleaving GC info with a disassembly listing, | ||
| // than we do in the jitdump case. (Note that the verbose argument to this method is | ||
| // distinct from the verbose on Compiler. |
There was a problem hiding this comment.
nit: missing closing paren
|
There needs to be a follow-up to change jitutils and superpmi.py to use this new flag when generating textual asm for diffs. |
|
Does this print anything for untracked lifetimes? Also perhaps (as another follow-on) we need some sort of "overall summary" that jit-analyze can use to more reliably point out gc info diffs. |
No, it doesn't. I didn't really consider that as part of "interleaving" GC info, since it is independent of intra-method code locations. The information is derivable from the assembly dump because untracked lclVars have no tracked index.
I'm not sure what that would look like that wouldn't just be an extraction of the dumps that are interleaved. It would seem to me that anything else would of necessity include offsets. Did you have some thoughts on this? |
src/coreclr/src/jit/emit.cpp
Outdated
| emitComp->lvaGetDesc(actualVarNum)->lvTracked) | ||
| { | ||
| VarSetOps::AddElemD(emitComp, debugThisGCrefVars, | ||
| emitComp->lvaGetDesc((unsigned)actualVarNum)->lvVarIndex); |
There was a problem hiding this comment.
| emitComp->lvaGetDesc((unsigned)actualVarNum)->lvVarIndex); | |
| emitComp->lvaGetDesc(actualVarNum)->lvVarIndex); |
So the key point there is that if someone makes a change that affects untracked lclVar GC info (e.g., by changing untracked to tracked, or tracked to untracked?) we'll see a textual diff? Continuing in the line of thinking that "any change to GC info show appear as a change to asm diffs", it's possible that some things in the GC header such as PSPSym could change without corresponding change in the displayed asm. Maybe we don't worry about these rare cases for asm diffs? |
Right, that was my thinking in saying that.
I'm not sure I'd say that. It would probably be worth some investment to ensure that such diffs would be visible. I'll make a note on the original issue (which I've re-opened, as I had a fix note in this PR). |
Some thoughts:
|
Output GC info delats after the instruction (or label) that changes it.
Add
COMPlus_JitDisasmWithGCoption to turn on the interleaving with assembly.Fix #41647