-
Notifications
You must be signed in to change notification settings - Fork 831
Source map fixes #6550
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
Source map fixes #6550
Conversation
1ecc106 to
2b0f16f
Compare
| } else if (self->getFunction()->prologLocation.size()) { | ||
| // The first instruction may inherit its location from the | ||
| // function prolog | ||
| locs[curr] = *self->getFunction()->prologLocation.begin(); |
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.
How does this ensure it only affects the first instruction and not later ones?
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.
It should affect later instructions as well.
This piece of code:
;;@ a:1:1
(func
;;@ a:1:1
(nop)
;;@ a:1:1
(nop)
)is printed as:
;;@ a:1:1
(func
(nop)
(nop)
)So they should result in the same debug information when read back.
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, you mean by the normal rules of propagating from the parent to children? So the first instruction inherits from the prolog, and children of the first instruction inherit from the first instruction, so effectively they inherit from the prologue too? If so that makes sense but the comment was confusing me. Perhaps The first instruction may inherit its location from the function prolog could be Instructions may inherit their locations from the function prolog. - ?
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.
Actually, on reading the code again, I think a simpler way to do this would be, instead of adding code here, to add code to getPrevious. That method could look at the function prologue if it does not find something else.
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 what you mean since getPrevious returns a pointer to an expression. Do you mean I should move some of the code here to getPrevious so that it returns an optional location instead?
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.
Maybe I'm missing something, but right now getPrevious is
Expression* getPrevious() {
if (expressionStack.empty()) {
return nullptr;
}
assert(expressionStack.size() >= 1);
return expressionStack[expressionStack.size() - 1];
}I am suggesting it be something like
Expression* getPrevious() {
if (expressionStack.empty()) {
// Use the prologue, if there is one.
if (self->getFunction()->prologLocation.size()) {
return *self->getFunction()->prologLocation.begin();
}
return nullptr;
}
assert(expressionStack.size() >= 1);
return expressionStack[expressionStack.size() - 1];
}Then this function needs no changes, and can keep calling getPrevious() on line 63 and if it returns a non-null value, to use that.
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 prologLocation has type std::set<Function::DebugLocation>.
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, right. Then more code would need to move into getPrevious, and then really it would need to be renamed. I agree it's not worth it, sorry for not thinking this totally through.
kripken
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.
Aside from the comments this looks right to me. I also verified it does not break any debug/source-map tests in Emscripten, which gives additional confidence.
| if (func->epilogLocation.size()) { | ||
| parent.writeDebugLocation(*func->epilogLocation.begin()); | ||
| } else { | ||
| parent.writeNoDebugLocation(); |
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 this needed, since we prevent smearing across functions in another way anyhow? That is, this is the end of the function, so marking no-debug will not help any code but the next function, which is already handled by this PR elsewhere I think.
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 to prevent the debug location on the last instruction to smear on the function epilogue (that is, the end opcode at the end of the function code). So that this:
(func
;;@ a:1:1
(nop)
;;@
)does not get turned into this:
(func
;;@ a:1:1
(nop)
;;@ a:1:1
)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 see, thanks. Maybe add a comment saying that?
The `fn_prolog_epilog.debugInfo` test is failing otherwise, since there was debug information associated to the nop instruction at the beginning of the function.
…e map The last segment should extend to the end of the function.
The text parser no longer propagates locations to the epilogue, so we should always print the location if there is one.
The debug location of the last instruction should not smear into the function epilogue, and a debug location from a previous function should not smear into the prologue of the current function.
Co-authored-by: Alon Zakai <[email protected]>
|
Before we land this, can you please merge in latest |
This is done already. I only had to make a small change to the Stack IR source map support (see last commit). |
|
Thanks, I see, I missed that this was forced pushed and I was looking for a merge commit... |
Some debug locations could be dropped at the beginning and end of functions:
Also, the binary writer was smearing the debug location of the last instruction to the function epilogue, and the debug location of a previous function could smear to the prologue of the next function.