[Fb-contrib-commit] SF.net SVN: fb-contrib:[1148] trunk/fb-contrib/src/com/mebigfatguy/ fbcontrib/
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2009-03-17 06:36:33
|
Revision: 1148
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1148&view=rev
Author: dbrosius
Date: 2009-03-17 06:36:26 +0000 (Tue, 17 Mar 2009)
Log Message:
-----------
track objects on which method calls are made associated with stores, and clear the store regs when that same object has another method call on it.
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2009-03-17 05:41:35 UTC (rev 1147)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2009-03-17 06:36:26 UTC (rev 1148)
@@ -29,6 +29,7 @@
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.CodeException;
import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.Type;
import com.mebigfatguy.fbcontrib.utils.Integer14;
import com.mebigfatguy.fbcontrib.utils.RegisterUtils;
@@ -36,7 +37,9 @@
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.BytecodeScanningDetector;
+import edu.umd.cs.findbugs.OpcodeStack;
import edu.umd.cs.findbugs.ba.ClassContext;
+import edu.umd.cs.findbugs.ba.XField;
/**
* looks for variable assignments at a scope larger than its use. In this case,
@@ -46,6 +49,7 @@
public class BloatedAssignmentScope extends BytecodeScanningDetector
{
BugReporter bugReporter;
+ private OpcodeStack stack;
private Set<Integer> ignoreRegs;
private ScopeBlock rootScopeBlock;
private Set<Integer> catchHandlers;
@@ -76,12 +80,14 @@
catchHandlers = new HashSet<Integer>();
switchTargets = new HashSet<Integer>();
monitorSyncPCs = new ArrayList<Integer>();
+ stack = new OpcodeStack();
super.visitClassContext(classContext);
} finally {
ignoreRegs = null;
catchHandlers = null;
switchTargets = null;
monitorSyncPCs = null;
+ stack = null;
}
}
@@ -97,7 +103,9 @@
ignoreRegs.clear();
Method method = getMethod();
if (!method.isStatic())
- ignoreRegs.add(Integer14.valueOf(0));
+ {
+ ignoreRegs.add(Integer14.valueOf(0));
+ }
int[] parmRegs = RegisterUtils.getParameterRegisters(method);
for (int parm : parmRegs) {
@@ -114,13 +122,16 @@
}
switchTargets.clear();
+ stack.resetForMethodEntry(this);
dontReport = false;
sawDup = false;
sawNull = false;
super.visitCode(obj);
if (!dontReport)
+ {
rootScopeBlock.findBugs(new HashSet<Integer>());
+ }
} finally {
rootScopeBlock = null;
@@ -135,159 +146,257 @@
*/
@Override
public void sawOpcode(int seen) {
- if ((seen == ASTORE)
- || (seen == ISTORE)
- || (seen == LSTORE)
- || (seen == FSTORE)
- || (seen == DSTORE)
- || ((seen >= ASTORE_0) && (seen <= ASTORE_3))
- || ((seen >= ISTORE_0) && (seen <= ISTORE_3))
- || ((seen >= LSTORE_0) && (seen <= LSTORE_1))
- || ((seen >= FSTORE_0) && (seen <= FSTORE_1))
- || ((seen >= DSTORE_0) && (seen <= DSTORE_1))) {
- int reg = RegisterUtils.getStoreReg(this, seen);
- Integer iReg = Integer14.valueOf(reg);
- int pc = getPC();
- if (catchHandlers.contains(Integer14.valueOf(pc)))
- ignoreRegs.add(iReg);
- else if (monitorSyncPCs.size() > 0)
- ignoreRegs.add(iReg);
- else if (sawNull)
- ignoreRegs.add(iReg);
-
- if (!ignoreRegs.contains(iReg)) {
- ScopeBlock sb = findScopeBlock(rootScopeBlock, pc);
- if (sb != null) {
- sb.addStore(reg, pc);
- if (sawDup)
- sb.addLoad(reg, pc);
+ Object caller = null;
+ try {
+ if ((seen == ASTORE)
+ || (seen == ISTORE)
+ || (seen == LSTORE)
+ || (seen == FSTORE)
+ || (seen == DSTORE)
+ || ((seen >= ASTORE_0) && (seen <= ASTORE_3))
+ || ((seen >= ISTORE_0) && (seen <= ISTORE_3))
+ || ((seen >= LSTORE_0) && (seen <= LSTORE_1))
+ || ((seen >= FSTORE_0) && (seen <= FSTORE_1))
+ || ((seen >= DSTORE_0) && (seen <= DSTORE_1))) {
+ int reg = RegisterUtils.getStoreReg(this, seen);
+ Integer iReg = Integer14.valueOf(reg);
+ int pc = getPC();
+ if (catchHandlers.contains(Integer14.valueOf(pc)))
+ {
+ ignoreRegs.add(iReg);
}
- else
- ignoreRegs.add(iReg);
- }
- } else if (seen == IINC) {
- int reg = getRegisterOperand();
- Integer iReg = Integer14.valueOf(reg);
- if (!ignoreRegs.contains(iReg)) {
- ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
- if (sb != null)
- sb.addLoad(reg, getPC());
- else
- ignoreRegs.add(iReg);
- }
- int pc = getPC();
- if (catchHandlers.contains(Integer14.valueOf(pc)))
- ignoreRegs.add(iReg);
- else if (monitorSyncPCs.size() > 0)
- ignoreRegs.add(iReg);
- else if (sawNull)
- ignoreRegs.add(iReg);
-
- if (!ignoreRegs.contains(iReg)) {
- ScopeBlock sb = findScopeBlock(rootScopeBlock, pc);
- if (sb != null) {
- sb.addStore(reg, pc);
- if (sawDup)
- sb.addLoad(reg, pc);
+ else if (monitorSyncPCs.size() > 0)
+ {
+ ignoreRegs.add(iReg);
}
- else
- ignoreRegs.add(iReg);
- }
- } else if ((seen == ALOAD)
- || (seen == ILOAD)
- || (seen == LLOAD)
- || (seen == FLOAD)
- || (seen == DLOAD)
- || ((seen >= ALOAD_0) && (seen <= ALOAD_3))
- || ((seen >= ILOAD_0) && (seen <= ILOAD_3))
- || ((seen >= LLOAD_0) && (seen <= LLOAD_1))
- || ((seen >= FLOAD_0) && (seen <= FLOAD_1))
- || ((seen >= DLOAD_0) && (seen <= DLOAD_1))) {
- int reg = RegisterUtils.getLoadReg(this, seen);
- if (!ignoreRegs.contains(Integer14.valueOf(reg))) {
- ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
- if (sb != null)
- sb.addLoad(reg, getPC());
- else
- ignoreRegs.add(Integer14.valueOf(reg));
- }
- } else if (((seen >= IFEQ) && (seen <= GOTO)) || (seen == GOTO_W)) {
- int target = getBranchTarget();
- if (target > getPC()) {
- if ((seen == GOTO) || (seen == GOTO_W)) {
- Integer nextPC = Integer14.valueOf(getNextPC());
- if (!switchTargets.contains(nextPC)) {
- ScopeBlock sb = findScopeBlockWithTarget(rootScopeBlock, getPC(), getNextPC());
- if (sb == null) {
- sb = new ScopeBlock(getPC(), target);
- sb.setLoop();
- sb.setGoto();
- rootScopeBlock.addChild(sb);
- } else {
- sb = new ScopeBlock(getPC(), target);
- sb.setGoto();
- rootScopeBlock.addChild(sb);
- }
- }
- } else {
- ScopeBlock sb = findScopeBlockWithTarget(rootScopeBlock, getPC(), target);
- if ((sb != null) && (!sb.isLoop) && !sb.hasChildren()) {
- if (sb.isGoto()) {
- ScopeBlock parent = sb.getParent();
- sb.pushUpLoadStores();
- if (parent != null)
- parent.removeChild(sb);
- sb = new ScopeBlock(getPC(), target);
- rootScopeBlock.addChild(sb);
- } else {
- sb.pushUpLoadStores();
- sb.setStart(getPC());
- sb.setFinish(target);
+ else if (sawNull)
+ {
+ ignoreRegs.add(iReg);
+ }
+
+ if (!ignoreRegs.contains(iReg)) {
+ ScopeBlock sb = findScopeBlock(rootScopeBlock, pc);
+ if (sb != null) {
+ Object assoc = null;
+ if (stack.getStackDepth() > 0) {
+ assoc = stack.getStackItem(0).getUserValue();
+ }
+ sb.addStore(reg, pc, assoc);
+ if (sawDup)
+ {
+ sb.addLoad(reg, pc);
}
- } else {
- sb = new ScopeBlock(getPC(), target);
- rootScopeBlock.addChild(sb);
- }
+ }
+ else
+ {
+ ignoreRegs.add(iReg);
+ }
+ }
+ } else if (seen == IINC) {
+ int reg = getRegisterOperand();
+ Integer iReg = Integer14.valueOf(reg);
+ if (!ignoreRegs.contains(iReg)) {
+ ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
+ if (sb != null)
+ {
+ sb.addLoad(reg, getPC());
+ }
+ else
+ {
+ ignoreRegs.add(iReg);
+ }
+ }
+ int pc = getPC();
+ if (catchHandlers.contains(Integer14.valueOf(pc)))
+ {
+ ignoreRegs.add(iReg);
}
- } else {
- ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
- if (sb != null)
- sb.setLoop();
- }
- } else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) {
- int pc = getPC();
- int[] offsets = getSwitchOffsets();
- List<Integer> targets = new ArrayList<Integer>();
- for (int offset : offsets)
- targets.add(Integer14.valueOf(offset + pc));
- Integer defOffset = Integer14.valueOf(getDefaultSwitchOffset() + pc);
- if (!targets.contains(defOffset))
- targets.add(defOffset);
- Collections.sort(targets);
-
- Integer lastTarget = targets.get(0);
- for (int i = 1; i < targets.size(); i++) {
- Integer nextTarget = targets.get(i);
- ScopeBlock sb = new ScopeBlock(lastTarget.intValue(), nextTarget.intValue());
- rootScopeBlock.addChild(sb);
- lastTarget = nextTarget;
- }
- switchTargets.addAll(targets);
- } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) {
- if ("wasNull".equals(getNameConstantOperand())
- && "()Z".equals(getSigConstantOperand()))
- dontReport = true;
- } else if (seen == MONITORENTER) {
- monitorSyncPCs.add(Integer14.valueOf(getPC()));
- } else if (seen == MONITOREXIT) {
- if (monitorSyncPCs.size() > 0)
- monitorSyncPCs.remove(monitorSyncPCs.size() - 1);
+ else if (monitorSyncPCs.size() > 0)
+ {
+ ignoreRegs.add(iReg);
+ }
+ else if (sawNull)
+ {
+ ignoreRegs.add(iReg);
+ }
+
+ if (!ignoreRegs.contains(iReg)) {
+ ScopeBlock sb = findScopeBlock(rootScopeBlock, pc);
+ if (sb != null) {
+ sb.addStore(reg, pc, null);
+ if (sawDup)
+ {
+ sb.addLoad(reg, pc);
+ }
+ }
+ else
+ {
+ ignoreRegs.add(iReg);
+ }
+ }
+ } else if ((seen == ALOAD)
+ || (seen == ILOAD)
+ || (seen == LLOAD)
+ || (seen == FLOAD)
+ || (seen == DLOAD)
+ || ((seen >= ALOAD_0) && (seen <= ALOAD_3))
+ || ((seen >= ILOAD_0) && (seen <= ILOAD_3))
+ || ((seen >= LLOAD_0) && (seen <= LLOAD_1))
+ || ((seen >= FLOAD_0) && (seen <= FLOAD_1))
+ || ((seen >= DLOAD_0) && (seen <= DLOAD_1))) {
+ int reg = RegisterUtils.getLoadReg(this, seen);
+ if (!ignoreRegs.contains(Integer14.valueOf(reg))) {
+ ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
+ if (sb != null)
+ {
+ sb.addLoad(reg, getPC());
+ }
+ else
+ {
+ ignoreRegs.add(Integer14.valueOf(reg));
+ }
+ }
+ } else if (((seen >= IFEQ) && (seen <= GOTO)) || (seen == GOTO_W)) {
+ int target = getBranchTarget();
+ if (target > getPC()) {
+ if ((seen == GOTO) || (seen == GOTO_W)) {
+ Integer nextPC = Integer14.valueOf(getNextPC());
+ if (!switchTargets.contains(nextPC)) {
+ ScopeBlock sb = findScopeBlockWithTarget(rootScopeBlock, getPC(), getNextPC());
+ if (sb == null) {
+ sb = new ScopeBlock(getPC(), target);
+ sb.setLoop();
+ sb.setGoto();
+ rootScopeBlock.addChild(sb);
+ } else {
+ sb = new ScopeBlock(getPC(), target);
+ sb.setGoto();
+ rootScopeBlock.addChild(sb);
+ }
+ }
+ } else {
+ ScopeBlock sb = findScopeBlockWithTarget(rootScopeBlock, getPC(), target);
+ if ((sb != null) && (!sb.isLoop) && !sb.hasChildren()) {
+ if (sb.isGoto()) {
+ ScopeBlock parent = sb.getParent();
+ sb.pushUpLoadStores();
+ if (parent != null)
+ {
+ parent.removeChild(sb);
+ }
+ sb = new ScopeBlock(getPC(), target);
+ rootScopeBlock.addChild(sb);
+ } else {
+ sb.pushUpLoadStores();
+ sb.setStart(getPC());
+ sb.setFinish(target);
+ }
+ } else {
+ sb = new ScopeBlock(getPC(), target);
+ rootScopeBlock.addChild(sb);
+ }
+ }
+ } else {
+ ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
+ if (sb != null)
+ {
+ sb.setLoop();
+ }
+ }
+ } else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) {
+ int pc = getPC();
+ int[] offsets = getSwitchOffsets();
+ List<Integer> targets = new ArrayList<Integer>();
+ for (int offset : offsets)
+ {
+ targets.add(Integer14.valueOf(offset + pc));
+ }
+ Integer defOffset = Integer14.valueOf(getDefaultSwitchOffset() + pc);
+ if (!targets.contains(defOffset))
+ {
+ targets.add(defOffset);
+ }
+ Collections.sort(targets);
+
+ Integer lastTarget = targets.get(0);
+ for (int i = 1; i < targets.size(); i++) {
+ Integer nextTarget = targets.get(i);
+ ScopeBlock sb = new ScopeBlock(lastTarget.intValue(), nextTarget.intValue());
+ rootScopeBlock.addChild(sb);
+ lastTarget = nextTarget;
+ }
+ switchTargets.addAll(targets);
+ } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) {
+ if ("wasNull".equals(getNameConstantOperand())
+ && "()Z".equals(getSigConstantOperand()))
+ {
+ dontReport = true;
+ }
+
+ caller = getCallingObject();
+
+ if (caller != null) {
+ ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC());
+ if (sb != null) {
+ sb.removeByAssoc(caller);
+ }
+ }
+
+ } else if (seen == MONITORENTER) {
+ monitorSyncPCs.add(Integer14.valueOf(getPC()));
+ } else if (seen == MONITOREXIT) {
+ if (monitorSyncPCs.size() > 0)
+ {
+ monitorSyncPCs.remove(monitorSyncPCs.size() - 1);
+ }
+ }
+
+ sawDup = (seen == DUP);
+ sawNull = (seen == ACONST_NULL);
+ } finally {
+ stack.sawOpcode(this, seen);
+ if (caller != null) {
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ item.setUserValue(caller);
+ }
+ }
+ }
+ }
+
+ /**
+ * returns either a register number of a field reference of the object that a method is being called on,
+ * or null, if it can't be determined.
+ *
+ * @return either an Integer for a register, or a String for the field name, or null
+ */
+ private Object getCallingObject() {
+ String sig = getSigConstantOperand();
+ if ("V".equals(Type.getReturnType(sig)))
+ {
+ return null;
}
-
- sawDup = (seen == DUP);
- sawNull = (seen == ACONST_NULL);
+
+ Type[] types = Type.getArgumentTypes(sig);
+ if (stack.getStackDepth() <= types.length) {
+ return null;
+ }
+
+ OpcodeStack.Item caller = stack.getStackItem(types.length);
+ int reg = caller.getRegisterNumber();
+ if (reg >= 0)
+ {
+ return Integer.valueOf(reg);
+ }
+
+ /* We ignore the possibility of two fields with the same name in different classes */
+ XField f = caller.getXField();
+ if (f != null)
+ {
+ return f.getName();
+ }
+ return null;
}
-
/**
* returns the scope block in which this register was assigned, by traversing the scope block tree
*
@@ -302,7 +411,9 @@
for (ScopeBlock child : sb.children) {
ScopeBlock foundSb = findScopeBlock(child, pc);
if (foundSb != null)
- return foundSb;
+ {
+ return foundSb;
+ }
}
}
return sb;
@@ -322,7 +433,9 @@
ScopeBlock parentBlock = null;
if ((sb.startLocation < start) && (sb.finishLocation >= start)) {
if ((sb.finishLocation <= target) || (sb.isGoto() && !sb.isLoop()))
+ {
parentBlock = sb;
+ }
}
if (sb.children != null)
@@ -330,7 +443,9 @@
for (ScopeBlock child : sb.children) {
ScopeBlock targetBlock = findScopeBlockWithTarget(child, start, target);
if (targetBlock != null)
- return targetBlock;
+ {
+ return targetBlock;
+ }
}
}
@@ -348,6 +463,7 @@
private boolean isGoto;
private Map<Integer, Integer> loads;
private Map<Integer, Integer> stores;
+ private Map<Object, Integer> assocs;
private List<ScopeBlock> children;
/** construts a new scope block
@@ -363,6 +479,7 @@
isGoto = false;
loads = null;
stores = null;
+ assocs = null;
children = null;
}
@@ -458,13 +575,39 @@
* @param reg the register that was stored
* @param pc the instruction that did the store
*/
- public void addStore(int reg, int pc) {
+ public void addStore(int reg, int pc, Object assocObject) {
if (stores == null)
- stores = new HashMap<Integer, Integer>();
+ {
+ stores = new HashMap<Integer, Integer>();
+ }
stores.put(Integer14.valueOf(reg), Integer14.valueOf(pc));
+ if (assocs == null)
+ {
+ assocs = new HashMap<Object, Integer>();
+ }
+ assocs.put(assocObject, reg);
}
+ /**
+ * removes stores to registers that where retrieved from method calls on assocObject
+ *
+ * @param assocObject the object that a method call was just performed on
+ */
+ public void removeByAssoc(Object assocObject) {
+ if (assocs != null) {
+ Integer reg = assocs.remove(assocObject);
+ if (reg != null) {
+ if (loads != null) {
+ loads.remove(reg);
+ }
+ if (stores != null) {
+ stores.remove(reg);
+ }
+ }
+ }
+ }
+
/**
* adds the register as a load in this scope block
*
@@ -473,7 +616,9 @@
*/
public void addLoad(int reg, int pc) {
if (loads == null)
- loads = new HashMap<Integer, Integer>();
+ {
+ loads = new HashMap<Integer, Integer>();
+ }
loads.put(Integer14.valueOf(reg), Integer14.valueOf(pc));
}
@@ -514,7 +659,9 @@
*/
public void removeChild(ScopeBlock child) {
if (children != null)
+ {
children.remove(child);
+ }
}
/**
@@ -522,17 +669,25 @@
*/
public void findBugs(Set<Integer> parentUsedRegs) {
if (isLoop)
- return;
+ {
+ return;
+ }
Set<Integer> usedRegs = new HashSet<Integer>(parentUsedRegs);
if (stores != null)
+ {
usedRegs.addAll(stores.keySet());
+ }
if (loads != null)
+ {
usedRegs.addAll(loads.keySet());
+ }
if (stores != null) {
if (loads != null)
- stores.keySet().removeAll(loads.keySet());
+ {
+ stores.keySet().removeAll(loads.keySet());
+ }
stores.keySet().removeAll(parentUsedRegs);
if (stores.size() > 0) {
@@ -577,14 +732,20 @@
*/
public boolean usesReg(Integer reg) {
if ((loads != null) && (loads.containsKey(reg)))
- return true;
+ {
+ return true;
+ }
if ((stores != null) && (stores.containsKey(reg)))
- return true;
+ {
+ return true;
+ }
if (children != null) {
for (ScopeBlock child : children) {
if (child.usesReg(reg))
- return true;
+ {
+ return true;
+ }
}
}
@@ -598,15 +759,23 @@
if (parent != null) {
if (loads != null) {
if (parent.loads != null)
- parent.loads.putAll(loads);
- else
- parent.loads = loads;
+ {
+ parent.loads.putAll(loads);
+ }
+ else
+ {
+ parent.loads = loads;
+ }
}
if (stores != null) {
if (parent.stores != null)
- parent.stores.putAll(stores);
- else
- parent.stores = stores;
+ {
+ parent.stores.putAll(stores);
+ }
+ else
+ {
+ parent.stores = stores;
+ }
}
loads = null;
stores = null;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|