Search in sources :

Example 11 with LabelNode

use of jdk.internal.org.objectweb.asm.tree.LabelNode in project Bytecoder by mirkosertic.

the class JSRInlinerAdapter method markSubroutineWalkDFS.

/**
 * Performs a simple DFS of the instructions, assigning each to the
 * subroutine <code>sub</code>. Starts from <code>index</code>. Invoked only
 * by <code>markSubroutineWalk()</code>.
 *
 * @param sub
 *            the subroutine whose instructions must be computed.
 * @param index
 *            an instruction of this subroutine.
 * @param anyvisited
 *            indexes of the already visited instructions, i.e. marked as
 *            part of this subroutine or any previously computed subroutine.
 */
private void markSubroutineWalkDFS(final BitSet sub, int index, final BitSet anyvisited) {
    while (true) {
        AbstractInsnNode node = instructions.get(index);
        // don't visit a node twice
        if (sub.get(index)) {
            return;
        }
        sub.set(index);
        // check for those nodes already visited by another subroutine
        if (anyvisited.get(index)) {
            dualCitizens.set(index);
            if (LOGGING) {
                log("Instruction #" + index + " is dual citizen.");
            }
        }
        anyvisited.set(index);
        if (node.getType() == AbstractInsnNode.JUMP_INSN && node.getOpcode() != JSR) {
            // we do not follow recursively called subroutines here; but any
            // other sort of branch we do follow
            JumpInsnNode jnode = (JumpInsnNode) node;
            int destidx = instructions.indexOf(jnode.label);
            markSubroutineWalkDFS(sub, destidx, anyvisited);
        }
        if (node.getType() == AbstractInsnNode.TABLESWITCH_INSN) {
            TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
            int destidx = instructions.indexOf(tsnode.dflt);
            markSubroutineWalkDFS(sub, destidx, anyvisited);
            for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
                LabelNode l = tsnode.labels.get(i);
                destidx = instructions.indexOf(l);
                markSubroutineWalkDFS(sub, destidx, anyvisited);
            }
        }
        if (node.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
            LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
            int destidx = instructions.indexOf(lsnode.dflt);
            markSubroutineWalkDFS(sub, destidx, anyvisited);
            for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
                LabelNode l = lsnode.labels.get(i);
                destidx = instructions.indexOf(l);
                markSubroutineWalkDFS(sub, destidx, anyvisited);
            }
        }
        // or not; if not, return.
        switch(instructions.get(index).getOpcode()) {
            case GOTO:
            case RET:
            case TABLESWITCH:
            case LOOKUPSWITCH:
            case IRETURN:
            case LRETURN:
            case FRETURN:
            case DRETURN:
            case ARETURN:
            case RETURN:
            case ATHROW:
                /*
                 * note: this either returns from this subroutine, or a parent
                 * subroutine which invoked it
                 */
                return;
        }
        // Use tail recursion here in the form of an outer while loop to
        // avoid our stack growing needlessly:
        index++;
        // but this is more complicated).
        if (index >= instructions.size()) {
            return;
        }
    }
}
Also used : LabelNode(jdk.internal.org.objectweb.asm.tree.LabelNode) TableSwitchInsnNode(jdk.internal.org.objectweb.asm.tree.TableSwitchInsnNode) JumpInsnNode(jdk.internal.org.objectweb.asm.tree.JumpInsnNode) LookupSwitchInsnNode(jdk.internal.org.objectweb.asm.tree.LookupSwitchInsnNode) AbstractInsnNode(jdk.internal.org.objectweb.asm.tree.AbstractInsnNode)

Example 12 with LabelNode

use of jdk.internal.org.objectweb.asm.tree.LabelNode in project Bytecoder by mirkosertic.

the class JSRInlinerAdapter method visitJumpInsn.

/**
 * Detects a JSR instruction and sets a flag to indicate we will need to do
 * inlining.
 */
@Override
public void visitJumpInsn(final int opcode, final Label lbl) {
    super.visitJumpInsn(opcode, lbl);
    LabelNode ln = ((JumpInsnNode) instructions.getLast()).label;
    if (opcode == JSR && !subroutineHeads.containsKey(ln)) {
        subroutineHeads.put(ln, new BitSet());
    }
}
Also used : LabelNode(jdk.internal.org.objectweb.asm.tree.LabelNode) BitSet(java.util.BitSet) JumpInsnNode(jdk.internal.org.objectweb.asm.tree.JumpInsnNode)

Aggregations

LabelNode (jdk.internal.org.objectweb.asm.tree.LabelNode)12 JumpInsnNode (jdk.internal.org.objectweb.asm.tree.JumpInsnNode)10 AbstractInsnNode (jdk.internal.org.objectweb.asm.tree.AbstractInsnNode)8 LookupSwitchInsnNode (jdk.internal.org.objectweb.asm.tree.LookupSwitchInsnNode)8 TableSwitchInsnNode (jdk.internal.org.objectweb.asm.tree.TableSwitchInsnNode)8 BitSet (java.util.BitSet)6 TryCatchBlockNode (jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode)6 HashMap (java.util.HashMap)4 AbstractMap (java.util.AbstractMap)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Map (java.util.Map)2 Type (jdk.internal.org.objectweb.asm.Type)2 IincInsnNode (jdk.internal.org.objectweb.asm.tree.IincInsnNode)2 InsnList (jdk.internal.org.objectweb.asm.tree.InsnList)2 InsnNode (jdk.internal.org.objectweb.asm.tree.InsnNode)2 LocalVariableNode (jdk.internal.org.objectweb.asm.tree.LocalVariableNode)2 VarInsnNode (jdk.internal.org.objectweb.asm.tree.VarInsnNode)2