final boolean forward = myDfa.isForward();
final int[] order = ControlFlowUtil.postOrder(myFlow);
+// Count limit for number of iterations per worklist
+ final int limit = getIterationLimit(forward);
int dfaCount = 0;
final long startTime = System.nanoTime();
break;
}
+ // Iteration count per one worklist
+ int count = 0;
final Instruction instruction = myFlow[order[i]];
final int number = instruction.num();
worklist.add(instruction);
visited[number] = true;
+ // It is essential to apply this check!!!
+ // This gives us more chances that resulting info will be closer to expected result
+ // Also it is used as indicator that "equals" method is implemented correctly in E
while (true) {
- dfaCount++;
+ count++;
+ if (count > limit){
+ if (LOG.isDebugEnabled()){
+ LOG.debug("Iteration count exceeded on worklist");
+ }
+ break;
+ }
final Instruction currentInstruction = worklist.poll();
if (currentInstruction == null) {
} else {
i--;
}
+ dfaCount += count;
}
if (LOG.isDebugEnabled()){
LOG.debug("Done in: " + (System.nanoTime() - startTime)/10e6 + "ms. Ratio: " + dfaCount / myFlow.length);
}
+ /**
+ * Count limit for dfa number of iterations.
+ * Every node in dfa should be processed <= pred times * 2
+ * Multiplier 2 is because of cycles.
+ */
+ private int getIterationLimit(final boolean forward) {
+ int allPred = myFlow.length;
+ for (Instruction instruction : myFlow) {
+ allPred += forward ? instruction.allPred().size() : instruction.allSucc().size();
+ }
+ return allPred * 2;
+ }
+
private DFAMap<E> join(final Instruction instruction, final List<DFAMap<E>> info) {
final Iterable<? extends Instruction> prev = myDfa.isForward() ? instruction.allPred() : instruction.allSucc();
final ArrayList<DFAMap<E>> prevInfos = new ArrayList<DFAMap<E>>();