Skip to main content
Jump to: navigation, search

JDT Core Programmer Guide/ECJ/Generate

< JDT Core Programmer Guide‎ | ECJ
Revision as of 06:42, 22 August 2020 by Stephan.herrmann.berlin.de (Talk | contribs) (initial content: participants & modes)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Note.png
The Code Generation phase is responsible for creating .class files in the format as defined in JVMS (see the spec page for latest versions). Also some errors are detected and reported only in this phase


Participants

  • This phase is driven by generatedCode() methods in individual AST classes.
  • The result is accumulated into an instance of org.eclipse.jdt.internal.compiler.ClassFile per type.
  • The work horse for all the details of byte code is class CodeStream, with its subclasses StackMapFrameCodeStream and TypeAnnotationCodeStream, which are used es required by the target Java version.

Modes

As mentioned above subtypes of CodeStream implement different capabilities:

  • stack maps are generated for 1.6 and above
  • type annotations are generated for 1.8 and above

Wide mode

Additionally, byte code can be generated in one of two addressing modes: regular and wide. In regular mode, relative code offsets must be smaller than 0x8000. In regular mode, opcodes like goto are used as opposed to goto_w in wide mode. Code generation always starts in regular mode, but as soon as a jump requires an offset larger than 0x7FFF code generation for the current method is aborted (by throwing new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, _), which causes a restart in AbstractMethodDeclaration.generateCode() or similar. The current mode is stored as CodeStream.wideMode.

A full restart is done, because instructions like goto vs goto_w have different size in bytes. So changing a goto instruction to become goto_w will invalidated all byte code offsets after the instruction. OTOH, jump offsets are only known once the target label has been placed into the stream. As a result code generation needs to now the length of a jump before the position of the jump target is known. The easiest way to find out is thus trial and error :)

Local variable optimization

Restarting code generation for a given method may also happen for another reason as detailed in bug 329709: local variables are assigned to byte code positions inside BlockScope.computeLocalVariablePositions(..), but for the sake of optimization, unused locals may not get a position assigned. For certain situations, however, usedness is found out only during generateCode() itself. So if code gen started thinking a local does not require a position, and later detects this assumption was wrong, a restart is triggered with CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE. (Details of bug 329709 may be filled in once bugzilla works again)

Back to the top