Thread: [Fb-contrib-commit] SF.net SVN: fb-contrib:[1520] trunk/fb-contrib/src/com/mebigfatguy/ fbcontrib/
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2010-03-13 20:52:44
|
Revision: 1520
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1520&view=rev
Author: dbrosius
Date: 2010-03-13 20:52:37 +0000 (Sat, 13 Mar 2010)
Log Message:
-----------
add static methods to PRMC
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2010-03-13 20:14:27 UTC (rev 1519)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2010-03-13 20:52:37 UTC (rev 1520)
@@ -111,6 +111,7 @@
private OpcodeStack stack = null;
private Map<Integer, MethodCall> localMethodCalls = null;
private Map<String, MethodCall> fieldMethodCalls = null;
+ private Map<String, MethodCall> staticMethodCalls = null;
private Set<Integer> branchTargets = null;
/**
@@ -132,12 +133,14 @@
stack = new OpcodeStack();
localMethodCalls = new HashMap<Integer, MethodCall>();
fieldMethodCalls = new HashMap<String, MethodCall>();
+ staticMethodCalls = new HashMap<String, MethodCall>();
branchTargets = new HashSet<Integer>();
super.visitClassContext(classContext);
} finally {
stack = null;
localMethodCalls = null;
fieldMethodCalls = null;
+ staticMethodCalls = null;
branchTargets = null;
}
}
@@ -187,12 +190,13 @@
localMethodCalls.remove(Integer.valueOf(RegisterUtils.getAStoreReg(this, seen)));
} else if (seen == PUTFIELD) {
fieldMethodCalls.remove(getNameConstantOperand());
- } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) {
+ } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE) || (seen == INVOKESTATIC)) {
String className = getClassConstantOperand();
String methodName = getNameConstantOperand();
String signature = getSigConstantOperand();
int parmCount = Type.getArgumentTypes(signature).length;
- if (stack.getStackDepth() > parmCount) {
+ int neededStackSize = parmCount - ((seen == INVOKESTATIC) ? 1 : 0);
+ if (stack.getStackDepth() > neededStackSize) {
Object[] parmConstants = new Object[parmCount];
for (int i = 0; i < parmCount; i++) {
OpcodeStack.Item parm = stack.getStackItem(i);
@@ -200,18 +204,28 @@
if (parmConstants[i] == null)
return;
}
- OpcodeStack.Item obj = stack.getStackItem(parmCount);
- int reg = obj.getRegisterNumber();
- XField field = obj.getXField();
+
MethodCall mc;
- if (reg >= 0) {
- mc = localMethodCalls.get(Integer.valueOf(reg));
- } else if (field != null) {
- mc = fieldMethodCalls.get(field.getName());
- } else
- return;
+ int reg = -1;
+ XField field = null;
+ if (seen == INVOKESTATIC) {
+ mc = staticMethodCalls.get(className);
+ } else {
+ OpcodeStack.Item obj = stack.getStackItem(parmCount);
+ reg = obj.getRegisterNumber();
+ field = obj.getXField();
+
+
+ if (reg >= 0) {
+ mc = localMethodCalls.get(Integer.valueOf(reg));
+ } else if (field != null) {
+ mc = fieldMethodCalls.get(field.getName());
+ } else
+ return;
+ }
+
if (mc != null) {
if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName)) {
Object[] parms = mc.getParms();
@@ -233,16 +247,25 @@
.addString(methodName + signature));
}
}
- if (reg >= 0) {
- localMethodCalls.remove(Integer.valueOf(reg));
+
+ if (seen == INVOKESTATIC) {
+ staticMethodCalls.remove(className);
} else {
- fieldMethodCalls.remove(field.getName());
+ if (reg >= 0) {
+ localMethodCalls.remove(Integer.valueOf(reg));
+ } else {
+ fieldMethodCalls.remove(field.getName());
+ }
}
} else {
- if (reg >= 0) {
- localMethodCalls.put(Integer.valueOf(reg), new MethodCall(methodName, signature, parmConstants));
- } else if (field != null) {
- fieldMethodCalls.put(field.getName(), new MethodCall(methodName, signature, parmConstants));
+ if (seen == INVOKESTATIC) {
+ staticMethodCalls.put(className, new MethodCall(methodName, signature, parmConstants));
+ } else {
+ if (reg >= 0) {
+ localMethodCalls.put(Integer.valueOf(reg), new MethodCall(methodName, signature, parmConstants));
+ } else if (field != null) {
+ fieldMethodCalls.put(field.getName(), new MethodCall(methodName, signature, parmConstants));
+ }
}
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dbr...@us...> - 2010-03-13 21:21:16
|
Revision: 1522
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1522&view=rev
Author: dbrosius
Date: 2010-03-13 21:21:09 +0000 (Sat, 13 Mar 2010)
Log Message:
-----------
clear the staticMethodCalls collection on new method
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2010-03-13 21:15:44 UTC (rev 1521)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2010-03-13 21:21:09 UTC (rev 1522)
@@ -155,6 +155,7 @@
stack.resetForMethodEntry(this);
localMethodCalls.clear();
fieldMethodCalls.clear();
+ staticMethodCalls.clear();
branchTargets.clear();
CodeException[] codeExceptions = obj.getExceptionTable();
for (CodeException codeEx : codeExceptions) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dbr...@us...> - 2010-03-13 21:43:03
|
Revision: 1523
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1523&view=rev
Author: dbrosius
Date: 2010-03-13 21:42:57 +0000 (Sat, 13 Mar 2010)
Log Message:
-----------
don't report currentTimeMillis
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2010-03-13 21:21:09 UTC (rev 1522)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2010-03-13 21:42:57 UTC (rev 1523)
@@ -74,6 +74,7 @@
riskyMethodNameContents.add("clone");
riskyMethodNameContents.add("close");
riskyMethodNameContents.add("copy");
+ riskyMethodNameContents.add("currentTimeMillis");
String userNameProp = System.getProperty(PRMC_RISKY_FIELD_USER_KEY);
if (userNameProp != null) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dbr...@us...> - 2011-04-22 05:14:38
|
Revision: 1662
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1662&view=rev
Author: dbrosius
Date: 2011-04-22 05:14:32 +0000 (Fri, 22 Apr 2011)
Log Message:
-----------
add find to the list of risky method names
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2011-03-25 23:43:53 UTC (rev 1661)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2011-04-22 05:14:32 UTC (rev 1662)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2011 Dave Brosius
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -42,7 +42,7 @@
* looks for calls of the same method on the same object when that object hasn't changed.
* This often is redundant, and the second call can be removed, or combined.
*/
-public class PossiblyRedundantMethodCalls extends BytecodeScanningDetector
+public class PossiblyRedundantMethodCalls extends BytecodeScanningDetector
{
public static final String PRMC_RISKY_FIELD_USER_KEY = "fbcontrib.PRMC.riskynames";
public static final String PRMC_RISKY_CLASS_USER_KEY = "fbcontrib.PRMC.riskyclasses";
@@ -50,18 +50,19 @@
public static final String PRMC_HIGH_METHODCALLS = "fbcontrib.PRMC.highmethodcalls";
public static final String PRMC_NORMAL_BYTECOUNT = "fbcontrib.PRMC.normalbytecount";
public static final String PRMC_NORMAL_METHODCALLS = "fbcontrib.PRMC.normalmethodcalls";
-
+
private static Set<String> riskyMethodNameContents = new HashSet<String>();
private static int highByteCountLimit = 200;
private static int highMethodCallLimit = 10;
private static int normalByteCountLimit = 50;
private static int normalMethodCallLimit = 4;
-
+
static {
riskyMethodNameContents.add("next");
riskyMethodNameContents.add("add");
riskyMethodNameContents.add("create");
riskyMethodNameContents.add("append");
+ riskyMethodNameContents.add("find");
riskyMethodNameContents.add("put");
riskyMethodNameContents.add("remove");
riskyMethodNameContents.add("read");
@@ -74,25 +75,30 @@
riskyMethodNameContents.add("close");
riskyMethodNameContents.add("copy");
riskyMethodNameContents.add("currentTimeMillis");
-
+
String userNameProp = System.getProperty(PRMC_RISKY_FIELD_USER_KEY);
if (userNameProp != null) {
String[] userNames = userNameProp.split("\\s*,\\s*");
- for (String name : userNames)
+ for (String name : userNames) {
riskyMethodNameContents.add(name);
+ }
}
Integer prop = Integer.getInteger(PRMC_HIGH_BYTECOUNT);
- if (prop != null)
+ if (prop != null) {
highByteCountLimit = prop.intValue();
+ }
prop = Integer.getInteger(PRMC_HIGH_METHODCALLS);
- if (prop != null)
+ if (prop != null) {
highMethodCallLimit = prop.intValue();
+ }
prop = Integer.getInteger(PRMC_NORMAL_BYTECOUNT);
- if (prop != null)
+ if (prop != null) {
normalByteCountLimit = prop.intValue();
+ }
prop = Integer.getInteger(PRMC_NORMAL_METHODCALLS);
- if (prop != null)
+ if (prop != null) {
normalMethodCallLimit = prop.intValue();
+ }
}
private static Set<String> riskyClassNames = new HashSet<String>();
static {
@@ -102,18 +108,19 @@
String userNameProp = System.getProperty(PRMC_RISKY_CLASS_USER_KEY);
if (userNameProp != null) {
String[] userNames = userNameProp.split("\\s*,\\s*");
- for (String name : userNames)
- riskyClassNames.add(name);
+ for (String name : userNames) {
+ riskyClassNames.add(name);
+ }
}
}
-
+
private final BugReporter bugReporter;
private OpcodeStack stack = null;
private Map<Integer, MethodCall> localMethodCalls = null;
private Map<String, MethodCall> fieldMethodCalls = null;
private Map<String, MethodCall> staticMethodCalls = null;
private Set<Integer> branchTargets = null;
-
+
/**
* constructs a PRMC detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -121,10 +128,10 @@
public PossiblyRedundantMethodCalls(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/**
* implements the visitor to create and clear the stack, method call maps, and branch targets
- *
+ *
* @param classContext the context object of the currently visited class
*/
@Override
@@ -144,10 +151,10 @@
branchTargets = null;
}
}
-
+
/**
* implements the visitor to reset the stack, and method call maps for new method
- *
+ *
* @param obj the context object of the currently parsed code block
*/
@Override
@@ -163,11 +170,11 @@
}
super.visitCode(obj);
}
-
+
/**
* implements the visitor to look for repetitive calls to the same method on the same object
* using the same constant parameters. These methods must return a value.
- *
+ *
* @param seen the opcode of the currently parsed instruction
*/
@Override
@@ -178,7 +185,7 @@
localMethodCalls.clear();
fieldMethodCalls.clear();
}
-
+
if (((seen >= IFEQ) && (seen <= GOTO)) || ((seen >= IFNULL) && (seen <= GOTO_W))) {
branchTargets.add(Integer.valueOf(getBranchTarget()));
} else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) {
@@ -202,44 +209,46 @@
for (int i = 0; i < parmCount; i++) {
OpcodeStack.Item parm = stack.getStackItem(i);
parmConstants[i] = parm.getConstant();
- if (parmConstants[i] == null)
+ if (parmConstants[i] == null) {
return;
+ }
}
-
-
+
+
MethodCall mc;
int reg = -1;
XField field = null;
-
+
if (seen == INVOKESTATIC) {
mc = staticMethodCalls.get(className);
} else {
OpcodeStack.Item obj = stack.getStackItem(parmCount);
reg = obj.getRegisterNumber();
field = obj.getXField();
-
-
+
+
if (reg >= 0) {
mc = localMethodCalls.get(Integer.valueOf(reg));
} else if (field != null) {
mc = fieldMethodCalls.get(field.getName());
- } else
+ } else {
return;
+ }
}
-
+
if (mc != null) {
if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName)) {
Object[] parms = mc.getParms();
if (Arrays.equals(parms, parmConstants)) {
Statistics statistics = Statistics.getStatistics();
Statistics.MethodInfo mi = statistics.getMethodStatistics(getClassConstantOperand(), methodName, signature);
-
- bugReporter.reportBug(new BugInstance(this, "PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS",
- (mi.numBytes >= highByteCountLimit || mi.numMethodCalls >= highMethodCallLimit) ?
+
+ bugReporter.reportBug(new BugInstance(this, "PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS",
+ ((mi.numBytes >= highByteCountLimit) || (mi.numMethodCalls >= highMethodCallLimit)) ?
HIGH_PRIORITY :
- (mi.numBytes >= normalByteCountLimit || mi.numMethodCalls >= normalMethodCallLimit) ?
+ ((mi.numBytes >= normalByteCountLimit) || (mi.numMethodCalls >= normalMethodCallLimit)) ?
NORMAL_PRIORITY :
- (mi.numBytes == 0 || mi.numMethodCalls == 0) ?
+ ((mi.numBytes == 0) || (mi.numMethodCalls == 0)) ?
LOW_PRIORITY :
EXP_PRIORITY)
.addClass(this)
@@ -248,7 +257,7 @@
.addString(methodName + signature));
}
}
-
+
if (seen == INVOKESTATIC) {
staticMethodCalls.remove(className);
} else {
@@ -275,7 +284,7 @@
stack.sawOpcode(this, seen);
}
}
-
+
/**
* returns true if the class or method name contains a pattern that is considered likely to be this modifying
*
@@ -284,16 +293,18 @@
* @return whether the method sounds like it modifies this
*/
private boolean isRiskyName(String className, String methodName) {
- if (riskyClassNames.contains(className))
- return true;
-
+ if (riskyClassNames.contains(className)) {
+ return true;
+ }
+
for (String riskyName : riskyMethodNameContents) {
- if (methodName.indexOf(riskyName) >= 0)
+ if (methodName.indexOf(riskyName) >= 0) {
return true;
+ }
}
return false;
}
-
+
/**
* contains information about a method call
*/
@@ -302,21 +313,21 @@
private final String methodName;
private final String methodSignature;
private final Object[] methodParms;
-
+
public MethodCall(String name, String signature, Object[] parms) {
methodName = name;
methodSignature = signature;
methodParms = parms;
}
-
+
public String getName() {
return methodName;
}
-
+
public String getSignature() {
return methodSignature;
}
-
+
public Object[] getParms() {
return methodParms;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|