-
Notifications
You must be signed in to change notification settings - Fork 1.1k
JSR-45: better support for debuging inlined calls #11492
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
Conversation
@@ -221,58 +225,15 @@ object Inliner { | |||
|
|||
/** Replace `Inlined` node by a block that contains its bindings and expansion */ | |||
def dropInlined(inlined: Inlined)(using Context): Tree = | |||
val topLevelClass = Some(inlined.call.symbol.topLevelClass).filter(_.exists) |
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 try
val topLevelClass = Some(inlined.call.symbol.topLevelClass).filter(_.exists) | |
val topLevelClass = | |
if inlined.call.isEmpty then None | |
else Some(inlined.call.symbol.topLevelClass) |
In theory, the symbol would not exist only if the inlined.call
is the EmptyTree.
/cc @errikos who might want to have a look |
also removes code that was relocationg inlined calls but now is unreachable
Fixes SMAP generation breaking bytecode idempotency assertions
@Kordyjan what's the status on this one? Are you planning to continue working on it or can it be closed? |
Haven't had time for that recently, but I definitely plan to continue my work on this solution. |
Nice to see this being worked on here 🙏 One idea for testing would be to use the JDI API; from a comment I made on the Scala 2 PR: https://gist.github.com/lrytz/a6a139491e3dad997c2d78d99b5bf504 |
That could be nice yes. We don't have that currently but we do have some tests that just check the behavior of jdb, with infrastructure in https://github.com/lampepfl/dotty/tree/master/compiler/test/debug and actual tests in https://github.com/lampepfl/dotty/tree/master/tests/debug |
Fixes #9715
This implements the same idea as scala/scala#9121, although due to differences in how inlining is handled in scala 2, the implementation for scala 3 is not using any code from the mentioned PR.
More info about
SourceDebugExtension
and SMAPs can be found here:How it works:
LineNumberTable
andSourceDebugExtension
. The number of these virtual lines is every time equal to the size of the line range of the expansion of inlined call.Scala
) is describing the mapping from the real source files to the real and virtual lines in our assumed source. The second stratum (ScalaDebug
) is mapping from virtual lines to corresponding inlined calls.SourceDebugExtension
InlinedSourceMap
about the position of all trees that have source different from the main source of the given compilation unit. The response to that request is the number of the virtual line that is corresponding to the particular line from the other source.LineNumberTable
andSourceDebugExtension
to correctly guess what line of the inlined method is currently executed. They can also construct stack frames for inlined calls.Example:
Let's assume we have two source files, each containing one function:
and
The classfile generated for the first sourcefile contains these two pieces:
and
The file contains two inlined calls, each having three lines of expansion. We assume then that its source has 10 lines: 4 - corresponding to the original file and 3 for each inline call. Let's analyze the
LineNumberTable
:Then let's take a look at the
Scala
stratum of our SMAP. It contains two files: 1 isUsage.scala
which is the main source of this classfile. Number 2 isInlined.scala
that contains the definition of inlined calls expansions. It contains three mappings:1,4:1
is describing lines 1-4 as lines 1-4 from the original file2#2,3:5
is describing lines 5-7 as lines 2-4 from file number 2 (the first inlined call)2#2,3:8
is describing lines 8-10 again as lines 2-4 from file number 2 (the second inlined call)The
ScalaDebug
stratum contains mappings necessary for the construction of stack frames for inlined calls in the debugger. It contains two mappings:2:5,3
is mapping line 2 to lines 5-7 which can be interpreted by debugger as lines 5-7 being a body of a function called from line 24:8,3
is mapping line 4 to lines 8-10 which can be interpreted by debugger as lines 8-10 being a body of a function called from line 4Notes about current implementation:
YCheckPosition
from the compiler pipeline as now we can represent in the bytecode positions coming from other sources. Should I repurpose it or should it be completely removed?LineNumberTable
. It will look like we are reentering the first call where we should enter the second one. The only solutions I can think about right now involve recursive applying of the same attachment to all trees in inlined call expansion or makingBCodeSkelBuilder.lineNumber
logic much more complicated by adding some context tracking entered inlined calls.