[Fb-contrib-commit] SF.net SVN: fb-contrib: [397] trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/det
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2006-04-04 15:22:38
|
Revision: 397 Author: dbrosius Date: 2006-04-04 08:22:32 -0700 (Tue, 04 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=397&view=rev Log Message: ----------- Fix for bug: [ 1462290 ] FCBL: infinite recursion? (stack overflow) Convert FCBL's algorithm from recursive to iterative, to avoid stack overflow problems. Modified Paths: -------------- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2006-04-04 14:38:03 UTC (rev 396) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2006-04-04 15:22:32 UTC (rev 397) @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.Map; import java.util.Set; @@ -184,65 +185,127 @@ * @param uncheckedFields the list of fields to look for */ private void checkBlock(BasicBlock bb, Set<String> uncheckedFields) { - visitedBlocks.set(bb.getId()); - InstructionIterator ii = bb.instructionIterator(); - while (ii.hasNext()) { - InstructionHandle ih = ii.next(); - Instruction ins = ih.getInstruction(); - if (ins instanceof FieldInstruction) { - FieldInstruction fi = (FieldInstruction) ins; - String fieldName = fi.getFieldName(cpg); - uncheckedFields.remove(fieldName); - - if (ins instanceof GETFIELD) { - localizableFields.remove(fieldName); - if (localizableFields.size() == 0) - return; - } else { - FieldInfo finfo = localizableFields.get(fieldName); - if (finfo != null) - finfo.setSrcLineAnnotation(SourceLineAnnotation.fromVisitedInstruction(clsContext, this, ih.getPosition())); - } - if (uncheckedFields.size() == 0) - return; - } - } + LinkedList<BlockState> toBeProcessed = new LinkedList<BlockState>(); + toBeProcessed.add(new BlockState(bb, uncheckedFields)); - if (uncheckedFields.size() > 0) { - Iterator<Edge> oei = cfg.outgoingEdgeIterator(bb); - while (oei.hasNext()) { - Edge e = oei.next(); - BasicBlock cb = e.getTarget(); - if (!visitedBlocks.get(cb.getId())) { - Set<String> subCheckedFields = new HashSet<String>(uncheckedFields); - checkBlock(cb, subCheckedFields); - if (localizableFields.size() == 0) + while (toBeProcessed.size() > 0) { + if (localizableFields.size() == 0) + return; + BlockState bState = toBeProcessed.removeFirst(); + bb = bState.getBasicBlock(); + uncheckedFields = bState.getUncheckedFields(); + + visitedBlocks.set(bb.getId()); + InstructionIterator ii = bb.instructionIterator(); + while (ii.hasNext()) { + InstructionHandle ih = ii.next(); + Instruction ins = ih.getInstruction(); + if (ins instanceof FieldInstruction) { + FieldInstruction fi = (FieldInstruction) ins; + String fieldName = fi.getFieldName(cpg); + uncheckedFields.remove(fieldName); + + if (ins instanceof GETFIELD) { + localizableFields.remove(fieldName); + if (localizableFields.size() == 0) + return; + } else { + FieldInfo finfo = localizableFields.get(fieldName); + if (finfo != null) + finfo.setSrcLineAnnotation(SourceLineAnnotation.fromVisitedInstruction(clsContext, this, ih.getPosition())); + } + if (uncheckedFields.size() == 0) return; + } + } + + if (uncheckedFields.size() > 0) { + Iterator<Edge> oei = cfg.outgoingEdgeIterator(bb); + while (oei.hasNext()) { + Edge e = oei.next(); + BasicBlock cb = e.getTarget(); + if (!visitedBlocks.get(cb.getId())) { + toBeProcessed.addLast(new BlockState(cb, uncheckedFields)); + } } } } } + /** + * holds information about a field and it's first usage + */ private static class FieldInfo { private FieldAnnotation fieldAnnotation; private SourceLineAnnotation srcLineAnnotation; + /** + * creates a FieldInfo from an annotation, and assumes no source line information + * @param fa the field annotation for this field + */ public FieldInfo(FieldAnnotation fa) { fieldAnnotation = fa; srcLineAnnotation = null; } + /** + * set the source line annotation of first use for this field + * @param sla the source line annotation + */ public void setSrcLineAnnotation(SourceLineAnnotation sla) { if (srcLineAnnotation == null) srcLineAnnotation = sla; } + /** + * get the field annotation for this field + * @return the field annotation + */ public FieldAnnotation getFieldAnnotation() { return fieldAnnotation; } + /** + * get the source line annotation for the first use of this field + * @return the source line annotation + */ public SourceLineAnnotation getSrcLineAnnotation() { return srcLineAnnotation; } } + + /** + * holds the parse state of the current basic block, and what fields are left to be checked + */ + private static class BlockState { + private BasicBlock basicBlock; + private Set<String> uncheckedFields; + + /** + * creates a BlockState consisting of the next basic block to parse, + * and what fields are to be checked + * @param bb the basic block to parse + * @param fields the fields to look for first use + */ + public BlockState(BasicBlock bb, Set<String> fields) { + basicBlock = bb; + uncheckedFields = new HashSet<String>(fields); + } + + /** + * get the basic block to parse + * @return the basic block + */ + public BasicBlock getBasicBlock() { + return basicBlock; + } + + /** + * get the unchecked fields to look for + * @return the unchecked fields + */ + public Set<String> getUncheckedFields() { + return uncheckedFields; + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |