Search in sources :

Example 6 with LookupSwitchInsnNode

use of jdk.internal.org.objectweb.asm.tree.LookupSwitchInsnNode 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)

Aggregations

AbstractInsnNode (jdk.internal.org.objectweb.asm.tree.AbstractInsnNode)6 JumpInsnNode (jdk.internal.org.objectweb.asm.tree.JumpInsnNode)6 LabelNode (jdk.internal.org.objectweb.asm.tree.LabelNode)6 LookupSwitchInsnNode (jdk.internal.org.objectweb.asm.tree.LookupSwitchInsnNode)6 TableSwitchInsnNode (jdk.internal.org.objectweb.asm.tree.TableSwitchInsnNode)6 TryCatchBlockNode (jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode)4 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)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 VarInsnNode (jdk.internal.org.objectweb.asm.tree.VarInsnNode)2