org.objectweb.asm.commons
Class JSRInlinerAdapter

java.lang.Object
  extended by org.objectweb.asm.tree.MemberNode
      extended by org.objectweb.asm.tree.MethodNode
          extended by org.objectweb.asm.commons.JSRInlinerAdapter
All Implemented Interfaces:
MethodVisitor, Opcodes

public class JSRInlinerAdapter
extends MethodNode
implements Opcodes

A MethodAdapter that removes JSR instructions and inlines the referenced subroutines. Explanation of how it works TODO

Author:
Niko Matsakis

Nested Class Summary
private  class JSRInlinerAdapter.Instantiation
          A class that represents an instantiation of a subroutine.
protected static class JSRInlinerAdapter.Subroutine
           
 
Field Summary
private  java.util.BitSet dualCitizens
          This BitSet contains the index of every instruction that belongs to more than one subroutine.
private static boolean LOGGING
           
private  JSRInlinerAdapter.Subroutine mainSubroutine
          This subroutine instance denotes the line of execution that is not contained within any subroutine; i.e., the "subroutine" that is executing when a method first begins.
private  MethodVisitor mv
          The visitor to which we will emit a translation of this method without internal subroutines.
private  java.util.Map subroutineHeads
          For each label that is jumped to by a JSR, we create a Subroutine instance.
 
Fields inherited from class org.objectweb.asm.tree.MethodNode
access, annotationDefault, desc, exceptions, instructions, invisibleParameterAnnotations, localVariables, maxLocals, maxStack, name, signature, tryCatchBlocks, visibleParameterAnnotations
 
Fields inherited from class org.objectweb.asm.tree.MemberNode
attrs, invisibleAnnotations, visibleAnnotations
 
Fields inherited from interface org.objectweb.asm.Opcodes
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6
 
Constructor Summary
JSRInlinerAdapter(MethodVisitor mv, int access, java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions)
          Creates a new JSRInliner.
 
Method Summary
private  void emitCode()
          Creates the new instructions, inlining each instantiation of each subroutine until the code is fully elaborated.
private  void emitSubroutine(JSRInlinerAdapter.Instantiation instant, java.util.List worklist, InsnList newInstructions, java.util.List newTryCatchBlocks, java.util.List newLocalVariables)
          Emits one instantiation of one subroutine, specified by instant.
private  void log(java.lang.String str)
           
private  void markSubroutines()
          Walks the method and determines which internal subroutine(s), if any, each instruction is a method of.
private  void markSubroutineWalk(JSRInlinerAdapter.Subroutine sub, int index, java.util.BitSet anyvisited)
          Performs a depth first search walking the normal byte code path starting at index, and adding each instruction encountered into the subroutine sub.
private  void markSubroutineWalkDFS(JSRInlinerAdapter.Subroutine sub, int index, java.util.BitSet anyvisited)
          Performs a simple DFS of the instructions, assigning each to the subroutine sub.
 void visitEnd()
          If any JSRs were seen, triggers the inlining process.
 void visitJumpInsn(int opcode, Label lbl)
          Detects a JSR instruction and sets a flag to indicate we will need to do inlining.
 
Methods inherited from class org.objectweb.asm.tree.MethodNode
accept, accept, visitAnnotationDefault, visitCode, visitFieldInsn, visitFrame, visitIincInsn, visitInsn, visitIntInsn, visitLabel, visitLdcInsn, visitLineNumber, visitLocalVariable, visitLookupSwitchInsn, visitMaxs, visitMethodInsn, visitMultiANewArrayInsn, visitParameterAnnotation, visitTableSwitchInsn, visitTryCatchBlock, visitTypeInsn, visitVarInsn
 
Methods inherited from class org.objectweb.asm.tree.MemberNode
visitAnnotation, visitAttribute
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.objectweb.asm.MethodVisitor
visitAnnotation, visitAttribute
 

Field Detail

LOGGING

private static final boolean LOGGING
See Also:
Constant Field Values

mv

private MethodVisitor mv
The visitor to which we will emit a translation of this method without internal subroutines.


subroutineHeads

private final java.util.Map subroutineHeads
For each label that is jumped to by a JSR, we create a Subroutine instance. Map is the generic type.


mainSubroutine

private final JSRInlinerAdapter.Subroutine mainSubroutine
This subroutine instance denotes the line of execution that is not contained within any subroutine; i.e., the "subroutine" that is executing when a method first begins.


dualCitizens

private final java.util.BitSet dualCitizens
This BitSet contains the index of every instruction that belongs to more than one subroutine. This should not happen often.

Constructor Detail

JSRInlinerAdapter

public JSRInlinerAdapter(MethodVisitor mv,
                         int access,
                         java.lang.String name,
                         java.lang.String desc,
                         java.lang.String signature,
                         java.lang.String[] exceptions)
Creates a new JSRInliner.

Parameters:
mv - the MethodVisitor to send the resulting inlined method code to (use null for none).
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.
desc - the method's descriptor (see Type).
signature - the method's signature. May be null.
exceptions - the internal names of the method's exception classes (see getInternalName). May be null.
Method Detail

visitJumpInsn

public void visitJumpInsn(int opcode,
                          Label lbl)
Detects a JSR instruction and sets a flag to indicate we will need to do inlining.

Specified by:
visitJumpInsn in interface MethodVisitor
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.
lbl - 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()
If any JSRs were seen, triggers the inlining process. Otherwise, forwards the byte codes untouched.

Specified by:
visitEnd in interface MethodVisitor
Overrides:
visitEnd in class MemberNode

markSubroutines

private void markSubroutines()
Walks the method and determines which internal subroutine(s), if any, each instruction is a method of.


markSubroutineWalk

private void markSubroutineWalk(JSRInlinerAdapter.Subroutine sub,
                                int index,
                                java.util.BitSet anyvisited)
Performs a depth first search walking the normal byte code path starting at index, and adding each instruction encountered into the subroutine sub. After this walk is complete, iterates over the exception handlers to ensure that we also include those byte codes which are reachable through an exception that may be thrown during the execution of the subroutine. Invoked from markSubroutines().

Parameters:
sub - TODO.
index - TODO.
anyvisited - TODO.

markSubroutineWalkDFS

private void markSubroutineWalkDFS(JSRInlinerAdapter.Subroutine sub,
                                   int index,
                                   java.util.BitSet anyvisited)
Performs a simple DFS of the instructions, assigning each to the subroutine sub. Starts from index. Invoked only by markSubroutineWalk().

Parameters:
sub - TODO.
index - TODO.
anyvisited - TODO.

emitCode

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


emitSubroutine

private void emitSubroutine(JSRInlinerAdapter.Instantiation instant,
                            java.util.List worklist,
                            InsnList newInstructions,
                            java.util.List newTryCatchBlocks,
                            java.util.List newLocalVariables)
Emits one instantiation of one subroutine, specified by instant. May add new instantiations that are invoked by this one to the worklist parameter, and new try/catch blocks to newTryCatchBlocks.

Parameters:
instant - TODO.
workList - TODO.
newInstructions - TODO.
newTryCatchBlocks - TODO.

log

private void log(java.lang.String str)