/** * Gets the register set associated with the start of the given * block. This is just convenient shorthand for * {@code getStarts(block.getLabel())}. * * @param block {@code non-null;} the block in question * @return {@code non-null;} the associated register set */ public RegisterSpecSet getStarts(BasicBlock block) { return getStarts(block.getLabel()); }
/** * Merges the given register set into the set for the block with the * given label. If there was not already an associated set, then this * is the same as calling {@link #setStarts}. Otherwise, this will * merge the two sets and call {@link #setStarts} on the result of the * merge. * * @param label {@code >= 0;} the block label * @param specs {@code non-null;} the register set to merge into the start set * for the block * @return {@code true} if the merge resulted in an actual change * to the associated set (including storing one for the first time) or * {@code false} if there was no change */ public boolean mergeStarts(int label, RegisterSpecSet specs) { RegisterSpecSet start = getStarts0(label); boolean changed = false; if (start == null) { setStarts(label, specs); return true; } RegisterSpecSet newStart = start.mutableCopy(); newStart.intersect(specs, true); if (start.equals(newStart)) { return false; } newStart.setImmutable(); setStarts(label, newStart); return true; }
RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label); BasicBlock block = blocks.labelToBlock(label); InsnList insns = block.getInsns(); resultInfo.addAssignment(insn, result); primaryState.put(result); primaryState : secondaryState; if (resultInfo.mergeStarts(succ, state)) { Bits.set(workSet, succ);
/** * Gets the register set associated with the start of the block * with the given label. This returns an empty set with the appropriate * max size if no set was associated with the block in question. * * @param label {@code >= 0;} the block label * @return {@code non-null;} the associated register set */ public RegisterSpecSet getStarts(int label) { RegisterSpecSet result = getStarts0(label); return (result != null) ? result : emptySet; }
/** * Adds a {@link LocalStart} to the output if the given * instruction in fact introduces a local variable. * * @param insn {@code non-null;} instruction in question */ public void addIntroductionIfNecessary(Insn insn) { RegisterSpec spec = locals.getAssignment(insn); if (spec != null) { addOutput(new LocalStart(insn.getPosition(), spec)); } } }
/** * Does the extraction. * * @return {@code non-null;} the extracted information */ private LocalVariableInfo doit() { for (int label = method.getFirstLabel(); label >= 0; label = Bits.findFirst(workSet, 0)) { Bits.clear(workSet, label); processBlock(label); } resultInfo.setImmutable(); return resultInfo; }
/** * Constructs an instance. This method is private. Use {@link #extract}. * * @param method {@code non-null;} the method to extract from */ private LocalVariableExtractor(RopMethod method) { if (method == null) { throw new NullPointerException("method == null"); } BasicBlockList blocks = method.getBlocks(); int maxLabel = blocks.getMaxLabel(); this.method = method; this.blocks = blocks; this.resultInfo = new LocalVariableInfo(method); this.workSet = Bits.makeBitSet(maxLabel); }
maxInsns += bsz + locals.getAssignmentCount();
RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label); BasicBlock block = blocks.labelToBlock(label); InsnList insns = block.getInsns(); resultInfo.addAssignment(insn, result); primaryState.put(result); primaryState : secondaryState; if (resultInfo.mergeStarts(succ, state)) { Bits.set(workSet, succ);
/** * Gets the register set associated with the start of the block * with the given label. This returns an empty set with the appropriate * max size if no set was associated with the block in question. * * @param label {@code >= 0;} the block label * @return {@code non-null;} the associated register set */ public RegisterSpecSet getStarts(int label) { RegisterSpecSet result = getStarts0(label); return (result != null) ? result : emptySet; }
/** * Adds a {@link LocalStart} to the output if the given * instruction in fact introduces a local variable. * * @param insn {@code non-null;} instruction in question */ public void addIntroductionIfNecessary(Insn insn) { RegisterSpec spec = locals.getAssignment(insn); if (spec != null) { addOutput(new LocalStart(insn.getPosition(), spec)); } } }
/** * Does the extraction. * * @return {@code non-null;} the extracted information */ private LocalVariableInfo doit() { for (int label = method.getFirstLabel(); label >= 0; label = Bits.findFirst(workSet, 0)) { Bits.clear(workSet, label); processBlock(label); } resultInfo.setImmutable(); return resultInfo; }
/** * Constructs an instance. This method is private. Use {@link #extract}. * * @param method {@code non-null;} the method to extract from */ private LocalVariableExtractor(RopMethod method) { if (method == null) { throw new NullPointerException("method == null"); } BasicBlockList blocks = method.getBlocks(); int maxLabel = blocks.getMaxLabel(); this.method = method; this.blocks = blocks; this.resultInfo = new LocalVariableInfo(method); this.workSet = Bits.makeBitSet(maxLabel); }
maxInsns += bsz + locals.getAssignmentCount();
RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label); BasicBlock block = blocks.labelToBlock(label); InsnList insns = block.getInsns(); resultInfo.addAssignment(insn, result); primaryState.put(result); primaryState : secondaryState; if (resultInfo.mergeStarts(succ, state)) { Bits.set(workSet, succ);
RegisterSpecSet start = getStarts0(label); setStarts(label, specs); return true; setStarts(label, newStart);
/** * Gets the register set associated with the start of the block * with the given label. This returns an empty set with the appropriate * max size if no set was associated with the block in question. * * @param label {@code >= 0;} the block label * @return {@code non-null;} the associated register set */ public RegisterSpecSet getStarts(int label) { RegisterSpecSet result = getStarts0(label); return (result != null) ? result : emptySet; }
/** * Gets the register set associated with the start of the given * block. This is just convenient shorthand for * {@code getStarts(block.getLabel())}. * * @param block {@code non-null;} the block in question * @return {@code non-null;} the associated register set */ public RegisterSpecSet getStarts(BasicBlock block) { return getStarts(block.getLabel()); }
/** * Adds a {@link LocalStart} to the output if the given * instruction in fact introduces a local variable. * * @param insn {@code non-null;} instruction in question */ public void addIntroductionIfNecessary(Insn insn) { RegisterSpec spec = locals.getAssignment(insn); if (spec != null) { addOutput(new LocalStart(insn.getPosition(), spec)); } } }
/** * Does the extraction. * * @return {@code non-null;} the extracted information */ private LocalVariableInfo doit() { for (int label = method.getFirstLabel(); label >= 0; label = Bits.findFirst(workSet, 0)) { Bits.clear(workSet, label); processBlock(label); } resultInfo.setImmutable(); return resultInfo; }