BasicBlockList toBasicBlocks() { if (!localsInitialized) { initializeLocals(); } cleanUpLabels(); BasicBlockList result = new BasicBlockList(labels.size()); for (int i = 0; i < labels.size(); i++) { result.set(i, labels.get(i).toBasicBlock()); } return result; }
/** * Gets the element at the given index. It is an error to call * this with the index for an element which was never set; if you * do that, this will throw {@code NullPointerException}. * * @param n {@code >= 0, < size();} which index * @return {@code non-null;} element at that index */ public BasicBlock get(int n) { return (BasicBlock) get0(n); }
/** * Returns an instance that is identical to this one, except that * the registers in each instruction are offset by the given * amount. Mutability of the result is inherited from the * original. * * @param delta the amount to offset register numbers by * @return {@code non-null;} an appropriately-constructed instance */ public BasicBlockList withRegisterOffset(int delta) { int sz = size(); BasicBlockList result = new BasicBlockList(sz); for (int i = 0; i < sz; i++) { BasicBlock one = (BasicBlock) get0(i); if (one != null) { result.set(i, one.withRegisterOffset(delta)); } } if (isImmutable()) { result.setImmutable(); } return result; }
/** * Constructs an instance. * * @param method {@code non-null;} the method being represented by this instance */ public LocalVariableInfo(RopMethod method) { if (method == null) { throw new NullPointerException("method == null"); } BasicBlockList blocks = method.getBlocks(); int maxLabel = blocks.getMaxLabel(); this.regCount = blocks.getRegCount(); this.emptySet = new RegisterSpecSet(regCount); this.blockStarts = new RegisterSpecSet[maxLabel]; this.insnAssignments = new HashMap<Insn, RegisterSpec>(blocks.getInstructionCount()); emptySet.setImmutable(); }
/** * Extracts the resulting {@link RopMethod} from the instance. * * @return {@code non-null;} the method object */ private RopMethod getRopMethod() { // Construct the final list of blocks. int sz = result.size(); BasicBlockList bbl = new BasicBlockList(sz); for (int i = 0; i < sz; i++) { bbl.set(i, result.get(i)); } bbl.setImmutable(); // Construct the method object to wrap it all up. /* * Note: The parameter assignment block is always the first * that should be executed, hence the second argument to the * constructor. */ return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT)); }
/** * Visits each instruction of each block in the list, in order. * * @param visitor {@code non-null;} visitor to use */ public void forEachInsn(Insn.Visitor visitor) { int sz = size(); for (int i = 0; i < sz; i++) { BasicBlock one = get(i); InsnList insns = one.getInsns(); insns.forEach(visitor); } }
/** * Gets the total instruction count for this instance. This is the * sum of the instruction counts of each block. * * @return {@code >= 0;} the total instruction count */ public int getInstructionCount() { int sz = size(); int result = 0; for (int i = 0; i < sz; i++) { BasicBlock one = (BasicBlock) getOrNull0(i); if (one != null) { result += one.getInsns().size(); } } return result; }
int bsz = blocks.size(); int maxInsns = (bsz * 3) + blocks.getInstructionCount(); this.regCount = blocks.getRegCount() + (paramsAreInOrder ? 0 : this.paramSize);
/** * Constructs an instance. * * @param ropMethod {@code non-null;} the original rop-form method that * this instance is based on * @param paramWidth the total width, in register-units, of the * method's parameters * @param isStatic {@code true} if this method has no {@code this} * pointer argument */ private SsaMethod(RopMethod ropMethod, int paramWidth, boolean isStatic) { this.paramWidth = paramWidth; this.isStatic = isStatic; this.backMode = false; this.maxLabel = ropMethod.getBlocks().getMaxLabel(); this.registerCount = ropMethod.getBlocks().getRegCount(); this.spareRegisterBase = registerCount; }
final int paramSize) { final boolean[] paramsAreInOrder = { true }; final int initialRegCount = method.getBlocks().getRegCount(); method.getBlocks().forEachInsn(new Insn.BaseVisitor() { @Override public void visitPlainCstInsn(PlainCstInsn insn) {
/** * Returns a mutable copy of this list. * * @return {@code non-null;} an appropriately-constructed instance */ public BasicBlockList getMutableCopy() { return new BasicBlockList(this); }
/** * Constructs an instance. * * @param method {@code non-null;} the method to have block addresses for */ public BlockAddresses(RopMethod method) { BasicBlockList blocks = method.getBlocks(); int maxLabel = blocks.getMaxLabel(); this.starts = new CodeAddress[maxLabel]; this.lasts = new CodeAddress[maxLabel]; this.ends = new CodeAddress[maxLabel]; setupArrays(method); }
/** * Replaces one of a block's successors with a different label. Constructs * an updated BasicBlock instance and places it in {@code newBlocks}. * * @param block block to replace * @param oldLabel label of successor to replace * @param newLabel label of new successor */ private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) { IntList newSuccessors = block.getSuccessors().mutableCopy(); int newPrimarySuccessor; newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel); newPrimarySuccessor = block.getPrimarySuccessor(); if (newPrimarySuccessor == oldLabel) { newPrimarySuccessor = newLabel; } newSuccessors.setImmutable(); BasicBlock newBB = new BasicBlock(block.getLabel(), block.getInsns(), newSuccessors, newPrimarySuccessor); newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB); } }
/** * Constructs instance. Call {@code process()} to run. * * @param rm {@code non-null;} instance to process */ public IdenticalBlockCombiner(RopMethod rm) { ropMethod = rm; blocks = ropMethod.getBlocks(); newBlocks = blocks.getMutableCopy(); }
/** * Returns how many registers this method requires. This is simply * the maximum of register-number-plus-category referred to by this * instance's instructions (indirectly through {@link BasicBlock} * instances). * * @return {@code >= 0;} the register count */ public int getRegCount() { if (regCount == -1) { RegCountVisitor visitor = new RegCountVisitor(); forEachInsn(visitor); regCount = visitor.getRegCount(); } return regCount; }
/** * Returns an instance that is identical to this one, except that * the registers in each instruction are offset by the given * amount. Mutability of the result is inherited from the * original. * * @param delta the amount to offset register numbers by * @return {@code non-null;} an appropriately-constructed instance */ public BasicBlockList withRegisterOffset(int delta) { int sz = size(); BasicBlockList result = new BasicBlockList(sz); for (int i = 0; i < sz; i++) { BasicBlock one = (BasicBlock) get0(i); if (one != null) { result.set(i, one.withRegisterOffset(delta)); } } if (isImmutable()) { result.setImmutable(); } return result; }
/** * Constructs an instance. * * @param method {@code non-null;} the method being represented by this instance */ public LocalVariableInfo(RopMethod method) { if (method == null) { throw new NullPointerException("method == null"); } BasicBlockList blocks = method.getBlocks(); int maxLabel = blocks.getMaxLabel(); this.regCount = blocks.getRegCount(); this.emptySet = new RegisterSpecSet(regCount); this.blockStarts = new RegisterSpecSet[maxLabel]; this.insnAssignments = new HashMap<Insn, RegisterSpec>(blocks.getInstructionCount()); emptySet.setImmutable(); }
/** * Extracts the resulting {@link RopMethod} from the instance. * * @return {@code non-null;} the method object */ private RopMethod getRopMethod() { // Construct the final list of blocks. int sz = result.size(); BasicBlockList bbl = new BasicBlockList(sz); for (int i = 0; i < sz; i++) { bbl.set(i, result.get(i)); } bbl.setImmutable(); // Construct the method object to wrap it all up. /* * Note: The parameter assignment block is always the first * that should be executed, hence the second argument to the * constructor. */ return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT)); }
/** * Visits each instruction of each block in the list, in order. * * @param visitor {@code non-null;} visitor to use */ public void forEachInsn(Insn.Visitor visitor) { int sz = size(); for (int i = 0; i < sz; i++) { BasicBlock one = get(i); InsnList insns = one.getInsns(); insns.forEach(visitor); } }
/** * Gets the total instruction count for this instance. This is the * sum of the instruction counts of each block. * * @return {@code >= 0;} the total instruction count */ public int getInstructionCount() { int sz = size(); int result = 0; for (int i = 0; i < sz; i++) { BasicBlock one = (BasicBlock) getOrNull0(i); if (one != null) { result += one.getInsns().size(); } } return result; }