Java Code Examples for com.android.dx.rop.code.Rop#getBranchingness()

The following examples show how to use com.android.dx.rop.code.Rop#getBranchingness() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RopTranslator.java    From buck with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
    SourcePosition pos = insn.getPosition();
    Constant cst = insn.getConstant();
    ArrayList<Constant> values = insn.getInitValues();
    Rop rop = insn.getOpcode();

    if (rop.getBranchingness() != Rop.BRANCH_NONE) {
        throw new RuntimeException("shouldn't happen");
    }
    CodeAddress dataAddress = new CodeAddress(pos);
    ArrayData dataInsn =
        new ArrayData(pos, lastAddress, values, cst);

    TargetInsn fillArrayDataInsn =
        new TargetInsn(Dops.FILL_ARRAY_DATA, pos, getRegs(insn),
                dataAddress);

    addOutput(lastAddress);
    addOutput(fillArrayDataInsn);

    addOutputSuffix(new OddSpacer(pos));
    addOutputSuffix(dataAddress);
    addOutputSuffix(dataInsn);
}
 
Example 2
Source File: RopTranslator.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitInvokePolymorphicInsn(InvokePolymorphicInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();

    if (rop.getBranchingness() != Rop.BRANCH_THROW) {
        throw new RuntimeException("Expected BRANCH_THROW got " + rop.getBranchingness());
    } else if (!rop.isCallLike()) {
        throw new RuntimeException("Expected call-like operation");
    }

    addOutput(lastAddress);

    RegisterSpecList regs = insn.getSources();
    Constant[] constants = new Constant[] {
        insn.getPolymorphicMethod(),
        insn.getCallSiteProto()
        };
    DalvInsn di = new MultiCstInsn(opcode, pos, regs, constants);

    addOutput(di);
}
 
Example 3
Source File: NormalSsaInsn.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 *
 * TODO: Increase the scope of this.
 */
@Override
public boolean hasSideEffect() {
    Rop opcode = getOpcode();

    if (opcode.getBranchingness() != Rop.BRANCH_NONE) {
        return true;
    }

    boolean hasLocalSideEffect
        = Optimizer.getPreserveLocals() && getLocalAssignment() != null;

    switch (opcode.getOpcode()) {
        case RegOps.MOVE_RESULT:
        case RegOps.MOVE:
        case RegOps.CONST:
            return hasLocalSideEffect;
        default:
            return true;
    }
}
 
Example 4
Source File: NormalSsaInsn.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 *
 * TODO: Increase the scope of this.
 */
@Override
public boolean hasSideEffect() {
    Rop opcode = getOpcode();

    if (opcode.getBranchingness() != Rop.BRANCH_NONE) {
        return true;
    }

    boolean hasLocalSideEffect
        = Optimizer.getPreserveLocals() && getLocalAssignment() != null;

    switch (opcode.getOpcode()) {
        case RegOps.MOVE_RESULT:
        case RegOps.MOVE:
        case RegOps.CONST:
            return hasLocalSideEffect;
        default:
            return true;
    }
}
 
Example 5
Source File: RopTranslator.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
      @Override
public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
          SourcePosition pos = insn.getPosition();
          Constant cst = insn.getConstant();
          ArrayList<Constant> values = insn.getInitValues();
          Rop rop = insn.getOpcode();

          if (rop.getBranchingness() != Rop.BRANCH_NONE) {
              throw new RuntimeException("shouldn't happen");
          }
          CodeAddress dataAddress = new CodeAddress(pos);
          ArrayData dataInsn =
              new ArrayData(pos, lastAddress, values, cst);

          TargetInsn fillArrayDataInsn =
              new TargetInsn(Dops.FILL_ARRAY_DATA, pos, getRegs(insn),
                      dataAddress);

          addOutput(lastAddress);
          addOutput(fillArrayDataInsn);

          addOutputSuffix(new OddSpacer(pos));
          addOutputSuffix(dataAddress);
          addOutputSuffix(dataInsn);
      }
 
Example 6
Source File: RopTranslator.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitInvokePolymorphicInsn(InvokePolymorphicInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();

    if (rop.getBranchingness() != Rop.BRANCH_THROW) {
        throw new RuntimeException("Expected BRANCH_THROW got " + rop.getBranchingness());
    } else if (!rop.isCallLike()) {
        throw new RuntimeException("Expected call-like operation");
    }

    addOutput(lastAddress);

    RegisterSpecList regs = insn.getSources();
    Constant[] constants = new Constant[] {
        insn.getInvokeMethod(),
        insn.getCallSiteProto()
        };
    DalvInsn di = new MultiCstInsn(opcode, pos, regs, constants);

    addOutput(di);
}
 
Example 7
Source File: RopTranslator.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitInvokePolymorphicInsn(InvokePolymorphicInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();

    if (rop.getBranchingness() != Rop.BRANCH_THROW) {
        throw new RuntimeException("Expected BRANCH_THROW got " + rop.getBranchingness());
    } else if (!rop.isCallLike()) {
        throw new RuntimeException("Expected call-like operation");
    }

    addOutput(lastAddress);

    RegisterSpecList regs = insn.getSources();
    Constant[] constants = new Constant[] {
        insn.getPolymorphicMethod(),
        insn.getCallSiteProto()
        };
    DalvInsn di = new MultiCstInsn(opcode, pos, regs, constants);

    addOutput(di);
}
 
Example 8
Source File: RopTranslator.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitThrowingInsn(ThrowingInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();
    RegisterSpec realResult;

    if (rop.getBranchingness() != Rop.BRANCH_THROW) {
        throw new RuntimeException("shouldn't happen");
    }

    realResult = getNextMoveResultPseudo();

    if (opcode.hasResult() != (realResult != null)) {
        throw new RuntimeException(
                "Insn with result/move-result-pseudo mismatch" + insn);
    }

    addOutput(lastAddress);

    DalvInsn di = new SimpleInsn(opcode, pos,
            getRegs(insn, realResult));

    addOutput(di);
}
 
Example 9
Source File: RopTranslator.java    From buck with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
public void visitThrowingInsn(ThrowingInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();
    RegisterSpec realResult;

    if (rop.getBranchingness() != Rop.BRANCH_THROW) {
        throw new RuntimeException("shouldn't happen");
    }

    realResult = getNextMoveResultPseudo();

    if (opcode.hasResult() != (realResult != null)) {
        throw new RuntimeException(
                "Insn with result/move-result-pseudo mismatch" + insn);
    }

    addOutput(lastAddress);

    DalvInsn di = new SimpleInsn(opcode, pos,
            getRegs(insn, realResult));

    addOutput(di);
}
 
Example 10
Source File: SsaToRop.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Validates that a basic block is a valid end predecessor. It must
 * end in a RETURN or a THROW. Throws a runtime exception on error.
 *
 * @param b {@code non-null;} block to validate
 * @throws RuntimeException on error
 */
private void verifyValidExitPredecessor(SsaBasicBlock b) {
    ArrayList<SsaInsn> insns = b.getInsns();
    SsaInsn lastInsn = insns.get(insns.size() - 1);
    Rop opcode = lastInsn.getOpcode();

    if (opcode.getBranchingness() != Rop.BRANCH_RETURN
            && opcode != Rops.THROW) {
        throw new RuntimeException("Exit predecessor must end"
                + " in valid exit statement.");
    }
}
 
Example 11
Source File: RopTranslator.java    From buck with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
public void visitPlainCstInsn(PlainCstInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();
    int ropOpcode = rop.getOpcode();
    DalvInsn di;

    if (rop.getBranchingness() != Rop.BRANCH_NONE) {
        throw new RuntimeException("shouldn't happen");
    }

    if (ropOpcode == RegOps.MOVE_PARAM) {
        if (!paramsAreInOrder) {
            /*
             * Parameters are not in order at the top of the reg space.
             * We need to add moves.
             */

            RegisterSpec dest = insn.getResult();
            int param =
                ((CstInteger) insn.getConstant()).getValue();
            RegisterSpec source =
                RegisterSpec.make(regCount - paramSize + param,
                        dest.getType());
            di = new SimpleInsn(opcode, pos,
                                RegisterSpecList.make(dest, source));
            addOutput(di);
        }
    } else {
        // No moves required for the parameters
        RegisterSpecList regs = getRegs(insn);
        di = new CstInsn(opcode, pos, regs, insn.getConstant());
        addOutput(di);
    }
}
 
Example 12
Source File: RopTranslator.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitPlainCstInsn(PlainCstInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();
    int ropOpcode = rop.getOpcode();
    DalvInsn di;

    if (rop.getBranchingness() != Rop.BRANCH_NONE) {
        throw new RuntimeException("shouldn't happen");
    }

    if (ropOpcode == RegOps.MOVE_PARAM) {
        if (!paramsAreInOrder) {
            /*
             * Parameters are not in order at the top of the reg space.
             * We need to add moves.
             */

            RegisterSpec dest = insn.getResult();
            int param =
                ((CstInteger) insn.getConstant()).getValue();
            RegisterSpec source =
                RegisterSpec.make(regCount - paramSize + param,
                        dest.getType());
            di = new SimpleInsn(opcode, pos,
                                RegisterSpecList.make(dest, source));
            addOutput(di);
        }
    } else {
        // No moves required for the parameters
        RegisterSpecList regs = getRegs(insn);
        di = new CstInsn(opcode, pos, regs, insn.getConstant());
        addOutput(di);
    }
}
 
Example 13
Source File: SsaToRop.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Validates that a basic block is a valid end predecessor. It must
 * end in a RETURN or a THROW. Throws a runtime exception on error.
 *
 * @param b {@code non-null;} block to validate
 * @throws RuntimeException on error
 */
private void verifyValidExitPredecessor(SsaBasicBlock b) {
    ArrayList<SsaInsn> insns = b.getInsns();
    SsaInsn lastInsn = insns.get(insns.size() - 1);
    Rop opcode = lastInsn.getOpcode();

    if (opcode.getBranchingness() != Rop.BRANCH_RETURN
            && opcode != Rops.THROW) {
        throw new RuntimeException("Exit predecessor must end"
                + " in valid exit statement.");
    }
}
 
Example 14
Source File: RopTranslator.java    From Box with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitPlainCstInsn(PlainCstInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();
    int ropOpcode = rop.getOpcode();
    DalvInsn di;

    if (rop.getBranchingness() != Rop.BRANCH_NONE) {
        throw new RuntimeException("shouldn't happen");
    }

    if (ropOpcode == RegOps.MOVE_PARAM) {
        if (!paramsAreInOrder) {
            /*
             * Parameters are not in order at the top of the reg space.
             * We need to add moves.
             */

            RegisterSpec dest = insn.getResult();
            int param =
                ((CstInteger) insn.getConstant()).getValue();
            RegisterSpec source =
                RegisterSpec.make(regCount - paramSize + param,
                        dest.getType());
            di = new SimpleInsn(opcode, pos,
                                RegisterSpecList.make(dest, source));
            addOutput(di);
        }
    } else {
        // No moves required for the parameters
        RegisterSpecList regs = getRegs(insn);
        di = new CstInsn(opcode, pos, regs, insn.getConstant());
        addOutput(di);
    }
}
 
Example 15
Source File: ConstCollector.java    From buck with Apache License 2.0 4 votes vote down vote up
/**
 * Applies the optimization.
 */
private void run() {
    int regSz = ssaMeth.getRegCount();

    ArrayList<TypedConstant> constantList
            = getConstsSortedByCountUse();

    int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);

    SsaBasicBlock start = ssaMeth.getEntryBlock();

    // Constant to new register containing the constant
    HashMap<TypedConstant, RegisterSpec> newRegs
            = new HashMap<TypedConstant, RegisterSpec> (toCollect);

    for (int i = 0; i < toCollect; i++) {
        TypedConstant cst = constantList.get(i);
        RegisterSpec result
                = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);

        Rop constRop = Rops.opConst(cst);

        if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
            start.addInsnToHead(
                    new PlainCstInsn(Rops.opConst(cst),
                            SourcePosition.NO_INFO, result,
                            RegisterSpecList.EMPTY, cst));
        } else {
            // We need two new basic blocks along with the new insn
            SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
            SsaBasicBlock successorBlock
                    = entryBlock.getPrimarySuccessor();

            // Insert a block containing the const insn.
            SsaBasicBlock constBlock
                    = entryBlock.insertNewSuccessor(successorBlock);

            constBlock.replaceLastInsn(
                    new ThrowingCstInsn(constRop, SourcePosition.NO_INFO,
                            RegisterSpecList.EMPTY,
                            StdTypeList.EMPTY, cst));

            // Insert a block containing the move-result-pseudo insn.

            SsaBasicBlock resultBlock
                    = constBlock.insertNewSuccessor(successorBlock);
            PlainInsn insn
                = new PlainInsn(
                        Rops.opMoveResultPseudo(result.getTypeBearer()),
                        SourcePosition.NO_INFO,
                        result, RegisterSpecList.EMPTY);

            resultBlock.addInsnToHead(insn);
        }

        newRegs.put(cst, result);
    }

    updateConstUses(newRegs, regSz);
}
 
Example 16
Source File: RopTranslator.java    From Box with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitPlainInsn(PlainInsn insn) {
    Rop rop = insn.getOpcode();
    if (rop.getOpcode() == RegOps.MARK_LOCAL) {
        /*
         * Ignore these. They're dealt with by
         * the LocalVariableAwareTranslationVisitor
         */
        return;
    }
    if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
        // These get skipped
        return;
    }

    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    DalvInsn di;

    switch (rop.getBranchingness()) {
        case Rop.BRANCH_NONE:
        case Rop.BRANCH_RETURN:
        case Rop.BRANCH_THROW: {
            di = new SimpleInsn(opcode, pos, getRegs(insn));
            break;
        }
        case Rop.BRANCH_GOTO: {
            /*
             * Code in the main translation loop will emit a
             * goto if necessary (if the branch isn't to the
             * immediately subsequent block).
             */
            return;
        }
        case Rop.BRANCH_IF: {
            int target = block.getSuccessors().get(1);
            di = new TargetInsn(opcode, pos, getRegs(insn),
                                addresses.getStart(target));
            break;
        }
        default: {
            throw new RuntimeException("shouldn't happen");
        }
    }

    addOutput(di);
}
 
Example 17
Source File: RopTranslator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Helper for {@link #outputInstructions}, which does the processing
 * and output of one block.
 *
 * @param block {@code non-null;} the block to process and output
 * @param nextLabel {@code >= -1;} the next block that will be processed, or
 * {@code -1} if there is no next block
 */
private void outputBlock(BasicBlock block, int nextLabel) {
    // Append the code address for this block.
    CodeAddress startAddress = addresses.getStart(block);
    output.add(startAddress);

    // Append the local variable state for the block.
    if (locals != null) {
        RegisterSpecSet starts = locals.getStarts(block);
        output.add(new LocalSnapshot(startAddress.getPosition(),
                                     starts));
    }

    /*
     * Choose and append an output instruction for each original
     * instruction.
     */
    translationVisitor.setBlock(block, addresses.getLast(block));
    block.getInsns().forEach(translationVisitor);

    // Insert the block end code address.
    output.add(addresses.getEnd(block));

    // Set up for end-of-block activities.

    int succ = block.getPrimarySuccessor();
    Insn lastInsn = block.getLastInsn();

    /*
     * Check for (and possibly correct for) a non-optimal choice of
     * which block will get output next.
     */

    if ((succ >= 0) && (succ != nextLabel)) {
        /*
         * The block has a "primary successor" and that primary
         * successor isn't the next block to be output.
         */
        Rop lastRop = lastInsn.getOpcode();
        if ((lastRop.getBranchingness() == Rop.BRANCH_IF) &&
                (block.getSecondarySuccessor() == nextLabel)) {
            /*
             * The block ends with an "if" of some sort, and its
             * secondary successor (the "then") is in fact the
             * next block to output. So, reverse the sense of
             * the test, so that we can just emit the next block
             * without an interstitial goto.
             */
            output.reverseBranch(1, addresses.getStart(succ));
        } else {
            /*
             * Our only recourse is to add a goto here to get the
             * flow to be correct.
             */
            TargetInsn insn =
                new TargetInsn(Dops.GOTO, lastInsn.getPosition(),
                        RegisterSpecList.EMPTY,
                        addresses.getStart(succ));
            output.add(insn);
        }
    }
}
 
Example 18
Source File: RopTranslator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
      @Override
public void visitPlainInsn(PlainInsn insn) {
          Rop rop = insn.getOpcode();
          if (rop.getOpcode() == RegOps.MARK_LOCAL) {
              /*
               * Ignore these. They're dealt with by
               * the LocalVariableAwareTranslationVisitor
               */
              return;
          }
          if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
              // These get skipped
              return;
          }

          SourcePosition pos = insn.getPosition();
          Dop opcode = RopToDop.dopFor(insn);
          DalvInsn di;

          switch (rop.getBranchingness()) {
              case Rop.BRANCH_NONE:
              case Rop.BRANCH_RETURN:
              case Rop.BRANCH_THROW: {
                  di = new SimpleInsn(opcode, pos, getRegs(insn));
                  break;
              }
              case Rop.BRANCH_GOTO: {
                  /*
                   * Code in the main translation loop will emit a
                   * goto if necessary (if the branch isn't to the
                   * immediately subsequent block).
                   */
                  return;
              }
              case Rop.BRANCH_IF: {
                  int target = block.getSuccessors().get(1);
                  di = new TargetInsn(opcode, pos, getRegs(insn),
                                      addresses.getStart(target));
                  break;
              }
              default: {
                  throw new RuntimeException("shouldn't happen");
              }
          }

          addOutput(di);
      }
 
Example 19
Source File: ConstCollector.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Applies the optimization.
 */
private void run() {
    int regSz = ssaMeth.getRegCount();

    ArrayList<TypedConstant> constantList
            = getConstsSortedByCountUse();

    int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);

    SsaBasicBlock start = ssaMeth.getEntryBlock();

    // Constant to new register containing the constant
    HashMap<TypedConstant, RegisterSpec> newRegs
            = new HashMap<TypedConstant, RegisterSpec> (toCollect);

    for (int i = 0; i < toCollect; i++) {
        TypedConstant cst = constantList.get(i);
        RegisterSpec result
                = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);

        Rop constRop = Rops.opConst(cst);

        if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
            start.addInsnToHead(
                    new PlainCstInsn(Rops.opConst(cst),
                            SourcePosition.NO_INFO, result,
                            RegisterSpecList.EMPTY, cst));
        } else {
            // We need two new basic blocks along with the new insn
            SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
            SsaBasicBlock successorBlock
                    = entryBlock.getPrimarySuccessor();

            // Insert a block containing the const insn.
            SsaBasicBlock constBlock
                    = entryBlock.insertNewSuccessor(successorBlock);

            constBlock.replaceLastInsn(
                    new ThrowingCstInsn(constRop, SourcePosition.NO_INFO,
                            RegisterSpecList.EMPTY,
                            StdTypeList.EMPTY, cst));

            // Insert a block containing the move-result-pseudo insn.

            SsaBasicBlock resultBlock
                    = constBlock.insertNewSuccessor(successorBlock);
            PlainInsn insn
                = new PlainInsn(
                        Rops.opMoveResultPseudo(result.getTypeBearer()),
                        SourcePosition.NO_INFO,
                        result, RegisterSpecList.EMPTY);

            resultBlock.addInsnToHead(insn);
        }

        newRegs.put(cst, result);
    }

    updateConstUses(newRegs, regSz);
}
 
Example 20
Source File: RopTranslator.java    From Box with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitPlainInsn(PlainInsn insn) {
    Rop rop = insn.getOpcode();
    if (rop.getOpcode() == RegOps.MARK_LOCAL) {
        /*
         * Ignore these. They're dealt with by
         * the LocalVariableAwareTranslationVisitor
         */
        return;
    }
    if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
        // These get skipped
        return;
    }

    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    DalvInsn di;

    switch (rop.getBranchingness()) {
        case Rop.BRANCH_NONE:
        case Rop.BRANCH_RETURN:
        case Rop.BRANCH_THROW: {
            di = new SimpleInsn(opcode, pos, getRegs(insn));
            break;
        }
        case Rop.BRANCH_GOTO: {
            /*
             * Code in the main translation loop will emit a
             * goto if necessary (if the branch isn't to the
             * immediately subsequent block).
             */
            return;
        }
        case Rop.BRANCH_IF: {
            int target = block.getSuccessors().get(1);
            di = new TargetInsn(opcode, pos, getRegs(insn),
                                addresses.getStart(target));
            break;
        }
        default: {
            throw new RuntimeException("shouldn't happen");
        }
    }

    addOutput(di);
}