Package org.objectweb.asm.commons
Class JSRInlinerAdapter
java.lang.Object
org.objectweb.asm.MethodVisitor
org.objectweb.asm.tree.MethodNode
org.objectweb.asm.commons.JSRInlinerAdapter
- All Implemented Interfaces:
Opcodes
A
MethodVisitor that removes JSR instructions and inlines the
referenced subroutines.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate final classAn instantiation of a subroutine. -
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final intThe default max memory limit forsetComputeLimits(int, long).(package private) static final longThe default max operations limit forsetComputeLimits(int, long).private static final intThe size of a LabelNode and of its nested Label, in bytes.private static final intThe size of a LocalVariableNode in bytes.private final BitSetThe instructions that belong to the main "subroutine".(package private) intThe number of instructions after inlining.(package private) intThe number of bytes which can be allocated.(package private) longThe number of operations which can be performed.(package private) final BitSetThe instructions that belong to more that one subroutine.The instructions that belong to each subroutine.private static final intThe size of a TryCatchBlockNode in bytes.Fields inherited from class org.objectweb.asm.tree.MethodNode
access, annotationDefault, attrs, desc, exceptions, instructions, invisibleAnnotableParameterCount, invisibleAnnotations, invisibleLocalVariableAnnotations, invisibleParameterAnnotations, invisibleTypeAnnotations, localVariables, maxLocals, maxStack, name, parameters, signature, tryCatchBlocks, visibleAnnotableParameterCount, visibleAnnotations, visibleLocalVariableAnnotations, visibleParameterAnnotations, visibleTypeAnnotationsFields inherited from class org.objectweb.asm.MethodVisitor
api, mvFields inherited from interface org.objectweb.asm.Opcodes
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_MODULE, ACC_NATIVE, ACC_OPEN, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_RECORD, ACC_STATIC, ACC_STATIC_PHASE, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_TRANSITIVE, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM10_EXPERIMENTAL, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9, 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, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, 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, INVOKEDYNAMIC, 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, SOURCE_DEPRECATED, SOURCE_MASK, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V_PREVIEW, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V9 -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedJSRInlinerAdapter(int api, MethodVisitor methodVisitor, int access, String name, String descriptor, String signature, String[] exceptions) Constructs a newJSRInlinerAdapter.JSRInlinerAdapter(MethodVisitor methodVisitor, int access, String name, String descriptor, String signature, String[] exceptions) Constructs a newJSRInlinerAdapter. -
Method Summary
Modifier and TypeMethodDescription(package private) voidcheckNewAllocation(int numBytes) Checks if some bytes can be allocated.(package private) voidcheckNewOperations(int numOperations) Checks if some operations can be done without exceeding the limit.private voidemitCode()Creates the new instructions, inlining each instantiation of each subroutine until the code is fully elaborated.private voidemitInstantiation(JSRInlinerAdapter.Instantiation instantiation, List<JSRInlinerAdapter.Instantiation> worklist, InsnList newInstructions, List<TryCatchBlockNode> newTryCatchBlocks, List<LocalVariableNode> newLocalVariables) Emits an instantiation of a subroutine, specified byinstantiation.private voidfindReachableInsns(int insnIndex, BitSet subroutineInsns, BitSet visitedInsns) Finds the instructions that are reachable from the given instruction, without following any JSR instruction nor any exception handler.private voidfindSubroutineInsns(int startInsnIndex, BitSet subroutineInsns, BitSet visitedInsns) Finds the instructions that belong to the subroutine starting at the given instruction index.private voidDetermines, for each instruction, to which subroutine(s) it belongs.voidsetComputeLimits(int maxBytes, long maxOperations) Sets the maximum number of bytes which can be allocated, and the maximum number of "operations" which can be performed, to inline the subroutines.voidvisitEnd()Visits the end of the method.voidvisitJumpInsn(int opcode, Label label) Visits a jump instruction.Methods inherited from class org.objectweb.asm.tree.MethodNode
accept, accept, check, getLabelNode, visitAnnotableParameterCount, visitAnnotation, visitAnnotationDefault, visitAttribute, visitCode, visitFieldInsn, visitFrame, visitIincInsn, visitInsn, visitInsnAnnotation, visitIntInsn, visitInvokeDynamicInsn, visitLabel, visitLdcInsn, visitLineNumber, visitLocalVariable, visitLocalVariableAnnotation, visitLookupSwitchInsn, visitMaxs, visitMethodInsn, visitMultiANewArrayInsn, visitParameter, visitParameterAnnotation, visitTableSwitchInsn, visitTryCatchAnnotation, visitTryCatchBlock, visitTypeAnnotation, visitTypeInsn, visitVarInsnMethods inherited from class org.objectweb.asm.MethodVisitor
getDelegate, visitMethodInsn
-
Field Details
-
DEFAULT_MAX_MEMORY_LIMIT
static final int DEFAULT_MAX_MEMORY_LIMITThe default max memory limit forsetComputeLimits(int, long). Update the comment insetComputeLimits(int, long)is you change this value.- See Also:
-
DEFAULT_MAX_OPERATIONS_LIMIT
static final long DEFAULT_MAX_OPERATIONS_LIMITThe default max operations limit forsetComputeLimits(int, long). Update the comment insetComputeLimits(int, long)is you change this value.- See Also:
-
LABEL_NODE_SIZE
private static final int LABEL_NODE_SIZEThe size of a LabelNode and of its nested Label, in bytes. Two object headers + (1 field + 6 inherited fields + padding) for LabelNode + 12 "equivalent int" fields for Label.- See Also:
-
TRY_CATCH_BLOCK_NODE_SIZE
private static final int TRY_CATCH_BLOCK_NODE_SIZEThe size of a TryCatchBlockNode in bytes. One object header + (6 fields + 6 inherited fields).- See Also:
-
LOCAL_VARIABLE_NODE_SIZE
private static final int LOCAL_VARIABLE_NODE_SIZEThe size of a LocalVariableNode in bytes. One object header + (6 fields + 6 inherited fields).- See Also:
-
mainSubroutineInsns
The instructions that belong to the main "subroutine". Bit i is set iff instruction at index i belongs to this main "subroutine". -
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. -
numInlinedInstructions
int numInlinedInstructionsThe number of instructions after inlining. -
remainingBytes
int remainingBytesThe number of bytes which can be allocated. -
remainingOperations
long remainingOperationsThe number of operations which can be performed.
-
-
Constructor Details
-
JSRInlinerAdapter
public JSRInlinerAdapter(MethodVisitor methodVisitor, int access, String name, String descriptor, String signature, String[] exceptions) Constructs a newJSRInlinerAdapter. Subclasses must not use this constructor. Instead, they must use theJSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])version.- Parameters:
methodVisitor- the method visitor to send the resulting inlined method code to, ornull.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 (seeType.getInternalName()). May be null.- Throws:
IllegalStateException- if a subclass calls this constructor.
-
JSRInlinerAdapter
protected JSRInlinerAdapter(int api, MethodVisitor methodVisitor, int access, String name, String descriptor, String signature, String[] exceptions) Constructs a newJSRInlinerAdapter.- Parameters:
api- the ASM API version implemented by this visitor. Must be one of theASMx values inOpcodes.methodVisitor- the method visitor to send the resulting inlined method code to, ornull.access- the method's access flags (seeOpcodes). 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 (seeType.getInternalName()). May be null.
-
-
Method Details
-
setComputeLimits
public void setComputeLimits(int maxBytes, long maxOperations) Sets the maximum number of bytes which can be allocated, and the maximum number of "operations" which can be performed, to inline the subroutines. Operations are not formally defined but their total number is deterministic and approximatively proportional to the computation time.The default limits should be sufficient for any "normal" class. You only need to set new limits if
visitEnd()throws aLimitExceededExceptionon some of your classes.- Parameters:
maxBytes- the maximum number of bytes which can be allocated. Not all object instantiations are tracked (and garbage collection is ignored), but the most important ones are. The default value is 20MB.maxOperations- the maximum number of "operations" that can be performed. The default value is 100M.
-
visitJumpInsn
Description copied from class:MethodVisitorVisits a jump instruction. A jump instruction is an instruction that may jump to another instruction.- Overrides:
visitJumpInsnin classMethodNode- 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:MethodVisitorVisits 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:
visitEndin classMethodNode
-
findSubroutinesInsns
private void findSubroutinesInsns()Determines, for each instruction, to which subroutine(s) it belongs. -
findSubroutineInsns
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
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, List<JSRInlinerAdapter.Instantiation> worklist, InsnList newInstructions, List<TryCatchBlockNode> newTryCatchBlocks, List<LocalVariableNode> newLocalVariables) Emits an instantiation of a subroutine, specified byinstantiation. May add new instantiations that are invoked by this one to theworklist, and new try/catch blocks tonewTryCatchBlocks.- 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.
-
checkNewAllocation
void checkNewAllocation(int numBytes) Checks if some bytes can be allocated.- Parameters:
numBytes- the number of bytes to allocate. Can be negative if an overflow occurs when computing it (e.g., if computed as a product "number of elements" * "size per element").- Throws:
LimitExceededException- if the memory limit is exceeded.
-
checkNewOperations
void checkNewOperations(int numOperations) Checks if some operations can be done without exceeding the limit.- Parameters:
numOperations- the number of operations to perform. Can be negative if an overflow occurs when computing it.- Throws:
LimitExceededException- if the memory limit is exceeded. LimitExceededException
-