javajvmjava-bytecode-asmjvm-bytecode

JVM byte code instructions, debug info source file as well as line number


I'm writing a compiler that generates JVM byte code, using the ASM library for the backend. It will be desirable to output debug information, so that stack traces can show source code locations where errors have occurred.

But it is dawning on me that there is a problem. From the ASM documentation:

Classes compiled with javac -g contain the name of their source file, a mapping between source line numbers and bytecode instructions, and a mapping betwen local variable names in source code and local variable slots in bytecode. This optional information is used in debuggers and in exception stack traces when it is available.

This implies that while each instruction can specify a source line, each entire class (let alone method) can only specify a single source file.

But I'm planning to do whole-program optimization, including aggressive cross-module inlining. That means many generated methods will contain chunks of code from different source files.

Is there any way to specify different source files for different parts of a method?


Solution

  • There is a dedicated attribute for this purpose, SourceDebugExtension. The contents of the second argument to visitSource​(source, debug) will be written into this attribute.

    You may notice that the linked JVM specification does not go into details about the contents of this attribute. But you can find an actual specification at https://download.oracle.com/otndocs/jcp/dsol-1.0-fr-spec-oth-JSpec/

    Keep in mind that this won’t affect stack traces which support a single source only, by design. JDK-4972961 suggested to change this, but has been closed with “won’t fix”. So, this attribute is only useful with debuggers actively supporting it.

    The conclusion is that before investing effort in generating this attribute, it’s worth investigating which tools actually support it and in which way. In other words, whether this work has a chance to pay off.