Class JSRInlinerAdapter

  • All Implemented Interfaces:
    Opcodes

    public class JSRInlinerAdapter
    extends MethodNode
    implements Opcodes
    A MethodVisitor that removes JSR instructions and inlines the referenced subroutines.
    • Field Detail

      • mainSubroutineInsns

        private final java.util.BitSet mainSubroutineInsns
        The instructions that belong to the main "subroutine". Bit i is set iff instruction at index i belongs to this main "subroutine".
      • subroutinesInsns

        private final java.util.Map<LabelNode,​java.util.BitSet> subroutinesInsns
        The instructions that belong to each subroutine. For each label which is the target of a JSR instruction, bit i of the corresponding BitSet in this map is set iff instruction at index i belongs to this subroutine.
      • sharedSubroutineInsns

        final java.util.BitSet sharedSubroutineInsns
        The instructions that belong to more that one subroutine. Bit i is set iff instruction at index i belongs to more than one subroutine.
    • Constructor Detail

      • JSRInlinerAdapter

        public JSRInlinerAdapter​(MethodVisitor methodVisitor,
                                 int access,
                                 java.lang.String name,
                                 java.lang.String descriptor,
                                 java.lang.String signature,
                                 java.lang.String[] exceptions)
        Constructs a new JSRInlinerAdapter. Subclasses must not use this constructor. Instead, they must use the JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[]) version.
        Parameters:
        methodVisitor - the method visitor to send the resulting inlined method code to, or null.
        access - the method's access flags.
        name - the method's name.
        descriptor - the method's descriptor.
        signature - the method's signature. May be null.
        exceptions - the internal names of the method's exception classes. May be null.
        Throws:
        java.lang.IllegalStateException - if a subclass calls this constructor.
      • JSRInlinerAdapter

        protected JSRInlinerAdapter​(int api,
                                    MethodVisitor methodVisitor,
                                    int access,
                                    java.lang.String name,
                                    java.lang.String descriptor,
                                    java.lang.String signature,
                                    java.lang.String[] exceptions)
        Constructs a new JSRInlinerAdapter.
        Parameters:
        api - the ASM API version implemented by this visitor. Must be one of Opcodes.ASM4, Opcodes.ASM5, Opcodes.ASM6, Opcodes.ASM7 or Opcodes.ASM8.
        methodVisitor - the method visitor to send the resulting inlined method code to, or null.
        access - the method's access flags (see Opcodes). This parameter also indicates if the method is synthetic and/or deprecated.
        name - the method's name.
        descriptor - the method's descriptor.
        signature - the method's signature. May be null.
        exceptions - the internal names of the method's exception classes. May be null.
    • Method Detail

      • visitJumpInsn

        public void visitJumpInsn​(int opcode,
                                  Label label)
        Description copied from class: MethodVisitor
        Visits a jump instruction. A jump instruction is an instruction that may jump to another instruction.
        Overrides:
        visitJumpInsn in class MethodNode
        Parameters:
        opcode - the opcode of the type instruction to be visited. This opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
        label - the operand of the instruction to be visited. This operand is a label that designates the instruction to which the jump instruction may jump.
      • visitEnd

        public void visitEnd()
        Description copied from class: MethodVisitor
        Visits the end of the method. This method, which is the last one to be called, is used to inform the visitor that all the annotations and attributes of the method have been visited.
        Overrides:
        visitEnd in class MethodNode
      • findSubroutinesInsns

        private void findSubroutinesInsns()
        Determines, for each instruction, to which subroutine(s) it belongs.
      • findSubroutineInsns

        private void findSubroutineInsns​(int startInsnIndex,
                                         java.util.BitSet subroutineInsns,
                                         java.util.BitSet visitedInsns)
        Finds the instructions that belong to the subroutine starting at the given instruction index. For this the control flow graph is visited with a depth first search (this includes the normal control flow and the exception handlers).
        Parameters:
        startInsnIndex - the index of the first instruction of the subroutine.
        subroutineInsns - where the indices of the instructions of the subroutine must be stored.
        visitedInsns - the indices of the instructions that have been visited so far (including in previous calls to this method). This bitset is updated by this method each time a new instruction is visited. It is used to make sure each instruction is visited at most once.
      • findReachableInsns

        private void findReachableInsns​(int insnIndex,
                                        java.util.BitSet subroutineInsns,
                                        java.util.BitSet visitedInsns)
        Finds the instructions that are reachable from the given instruction, without following any JSR instruction nor any exception handler. For this the control flow graph is visited with a depth first search.
        Parameters:
        insnIndex - the index of an instruction of the subroutine.
        subroutineInsns - where the indices of the instructions of the subroutine must be stored.
        visitedInsns - the indices of the instructions that have been visited so far (including in previous calls to this method). This bitset is updated by this method each time a new instruction is visited. It is used to make sure each instruction is visited at most once.
      • emitCode

        private void emitCode()
        Creates the new instructions, inlining each instantiation of each subroutine until the code is fully elaborated.
      • emitInstantiation

        private void emitInstantiation​(JSRInlinerAdapter.Instantiation instantiation,
                                       java.util.List<JSRInlinerAdapter.Instantiation> worklist,
                                       InsnList newInstructions,
                                       java.util.List<TryCatchBlockNode> newTryCatchBlocks,
                                       java.util.List<LocalVariableNode> newLocalVariables)
        Emits an instantiation of a subroutine, specified by instantiation. May add new instantiations that are invoked by this one to the worklist, and new try/catch blocks to newTryCatchBlocks.
        Parameters:
        instantiation - the instantiation that must be performed.
        worklist - list of the instantiations that remain to be done.
        newInstructions - the instruction list to which the instantiated code must be appended.
        newTryCatchBlocks - the exception handler list to which the instantiated handlers must be appended.
        newLocalVariables - the local variables list to which the instantiated local variables must be appended.