soft caching of bytecode info and small API changes

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@881 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2007-03-22 15:48:54 +00:00
parent 9f2055ac93
commit 2870d1dbc8
11 changed files with 147 additions and 211 deletions

View File

@ -916,6 +916,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
for (int i = basicBlock.getFirstInstructionIndex(); i <= basicBlock.getLastInstructionIndex(); i++) {
currentInstructionIndex = i;
instructions[i].visit(visitor);
if (DEBUG) {
Trace.println("After " + instructions[i] + " " + workingState);
}

View File

@ -22,6 +22,7 @@ import com.ibm.wala.fixedpoint.impl.NullaryOperator;
import com.ibm.wala.fixpoint.FixedPointConstants;
import com.ibm.wala.fixpoint.IVariable;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
@ -147,7 +148,13 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
IMethod m = cha.resolveMethod(call.getDeclaredTarget());
if (m != null) {
TypeReference[] x = m.getDeclaredExceptions();
TypeReference[] x = null;
try {
x = m.getDeclaredExceptions();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
if (x != null) {
for (int i = 0; i < x.length; i++) {
TypeReference tx = x[i];

View File

@ -15,6 +15,7 @@ import java.util.Iterator;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSACFG;
import com.ibm.wala.ssa.SSAInstruction;
@ -79,7 +80,13 @@ public class CFGSanitizer {
G.addEdge(b, exit);
} else {
// compute types of exceptions the pei may throw
TypeReference[] exceptions = computeExceptions(cha, s);
TypeReference[] exceptions = null;
try {
exceptions = computeExceptions(cha, s);
} catch (InvalidClassFileException e1) {
e1.printStackTrace();
Assertions.UNREACHABLE();
}
// remove any exceptions that are caught by catch blocks
for (Iterator it2 = cfg.getSuccNodes(b); it2.hasNext();) {
IBasicBlock c = (IBasicBlock) it2.next();
@ -108,7 +115,13 @@ public class CFGSanitizer {
}
}
// check the remaining uncaught exceptions
TypeReference[] declared = ir.getMethod().getDeclaredExceptions();
TypeReference[] declared = null;
try {
declared = ir.getMethod().getDeclaredExceptions();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
if (declared != null && exceptions != null) {
for (int i = 0; i < exceptions.length; i++) {
boolean isDeclared = false;
@ -139,7 +152,7 @@ public class CFGSanitizer {
return G;
}
private static TypeReference[] computeExceptions(ClassHierarchy cha, SSAInstruction s) {
private static TypeReference[] computeExceptions(ClassHierarchy cha, SSAInstruction s) throws InvalidClassFileException {
Collection c = null;
if (s instanceof SSAInvokeInstruction) {
SSAInvokeInstruction call = (SSAInvokeInstruction) s;
@ -159,4 +172,4 @@ public class CFGSanitizer {
}
}
} // CFGSanitizerImpl
}

View File

@ -11,6 +11,7 @@
package com.ibm.wala.classLoader;
import com.ibm.wala.ipa.callgraph.ContextItem;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.Selector;
@ -136,21 +137,24 @@ public interface IMethod extends IMember, ContextItem {
/**
* @return an array of the exception types declared by the throws clause for
* this method, or null if there are none
* @throws InvalidClassFileException
*/
TypeReference[] getDeclaredExceptions();
TypeReference[] getDeclaredExceptions() throws InvalidClassFileException;
/**
* @return the source line number corresponding to a particular bytecode
* index, or -1 if the information is not available.
* @throws InvalidClassFileException
*/
int getLineNumber(int bcIndex);
int getLineNumber(int bcIndex) throws InvalidClassFileException;
/**
* @return the (source code) name of the local variable of a given number at
* the specified program counter, or null if the information is not
* available.
* @throws InvalidClassFileException
*/
String getLocalVariableName(int bcIndex, int localNumber);
String getLocalVariableName(int bcIndex, int localNumber) throws InvalidClassFileException;
/**
* something like:

View File

@ -10,6 +10,7 @@
*******************************************************************************/
package com.ibm.wala.classLoader;
import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@ -130,11 +131,23 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
/**
* Cache the information about the method statements.
*/
protected BytecodeInfo bcInfo;
private SoftReference<BytecodeInfo> bcInfo;
public ShrikeBTMethod(IClass klass) {
this.declaringClass = klass;
}
protected BytecodeInfo getBCInfo() throws InvalidClassFileException {
BytecodeInfo result = null;
if (bcInfo != null) {
result = bcInfo.get();
}
if (result == null) {
result = computeBCInfo();
bcInfo = new SoftReference<BytecodeInfo>(result);
}
return result;
}
/**
* Return the program counter (bytecode index) for a particular Shrike
@ -143,13 +156,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
* @throws InvalidClassFileException
*/
public int getBytecodeIndex(int instructionIndex) throws InvalidClassFileException {
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return bcInfo.pcMap[instructionIndex];
return getBCInfo().pcMap[instructionIndex];
}
/**
@ -160,14 +167,8 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
Iterator<CallSiteReference> empty = EmptyIterator.instance();
return (bcInfo.callSites == null) ? empty : Arrays.asList(bcInfo.callSites).iterator();
return (getBCInfo().callSites == null) ? empty : Arrays.asList(getBCInfo().callSites).iterator();
}
/**
@ -178,14 +179,8 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
Iterator<NewSiteReference> empty = EmptyIterator.instance();
return (bcInfo.newSites == null) ? empty : Arrays.asList(bcInfo.newSites).iterator();
return (getBCInfo().newSites == null) ? empty : Arrays.asList(getBCInfo().newSites).iterator();
}
/**
@ -197,13 +192,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return Collections.EMPTY_SET;
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return (bcInfo.implicitExceptions == null) ? Arrays.asList(new TypeReference[0]) : Arrays.asList(bcInfo.implicitExceptions);
return (getBCInfo().implicitExceptions == null) ? Arrays.asList(new TypeReference[0]) : Arrays.asList(getBCInfo().implicitExceptions);
}
/**
@ -213,17 +202,13 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
*
* @throws InvalidClassFileException
*/
public void processBytecodes() throws InvalidClassFileException {
if (bcInfo != null) {
// already done.
return;
}
bcInfo = new BytecodeInfo();
bcInfo.exceptionTypes = computeDeclaredExceptions();
bcInfo.genericsSignature = computeGenericsSignature();
private BytecodeInfo computeBCInfo() throws InvalidClassFileException {
BytecodeInfo result = new BytecodeInfo();
result.exceptionTypes = computeDeclaredExceptions();
result.genericsSignature = computeGenericsSignature();
if (isNative()) {
return;
return result;
}
if (verbose) {
methodsParsed += 1;
@ -232,7 +217,8 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
}
}
processBytecodesWithShrikeBT();
processBytecodesWithShrikeBT(result);
return result;
}
/**
@ -243,13 +229,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return false;
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return bcInfo.hasMonitorOp;
return getBCInfo().hasMonitorOp;
}
/**
@ -260,16 +240,10 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
if (bcInfo.fieldsWritten == null) {
if (getBCInfo().fieldsWritten == null) {
return EmptyIterator.instance();
} else {
List<FieldReference> l = Arrays.asList(bcInfo.fieldsWritten);
List<FieldReference> l = Arrays.asList(getBCInfo().fieldsWritten);
return l.iterator();
}
}
@ -282,16 +256,10 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
if (bcInfo.fieldsRead == null) {
if (getBCInfo().fieldsRead == null) {
return EmptyIterator.instance();
} else {
List<FieldReference> l = Arrays.asList(bcInfo.fieldsRead);
List<FieldReference> l = Arrays.asList(getBCInfo().fieldsRead);
return l.iterator();
}
}
@ -304,14 +272,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return (bcInfo.arraysRead == null) ? EmptyIterator.instance() : Arrays.asList(bcInfo.arraysRead).iterator();
return (getBCInfo().arraysRead == null) ? EmptyIterator.instance() : Arrays.asList(getBCInfo().arraysRead).iterator();
}
/**
@ -322,14 +283,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return (bcInfo.arraysWritten == null) ? EmptyIterator.instance() : Arrays.asList(bcInfo.arraysWritten).iterator();
return (getBCInfo().arraysWritten == null) ? EmptyIterator.instance() : Arrays.asList(getBCInfo().arraysWritten).iterator();
}
/**
@ -340,14 +294,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
if (isNative()) {
return EmptyIterator.instance();
}
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return (bcInfo.castTypes == null) ? EmptyIterator.instance() : Arrays.asList(bcInfo.castTypes).iterator();
return (getBCInfo().castTypes == null) ? EmptyIterator.instance() : Arrays.asList(getBCInfo().castTypes).iterator();
}
protected abstract byte[] getBytecodes();
@ -459,23 +406,23 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
protected abstract void processDebugInfo(BytecodeInfo bcInfo) throws InvalidClassFileException;
private void processBytecodesWithShrikeBT() throws InvalidClassFileException {
bcInfo.decoder = makeDecoder();
private void processBytecodesWithShrikeBT(BytecodeInfo info) throws InvalidClassFileException {
info.decoder = makeDecoder();
if (Assertions.verifyAssertions) {
if (!isAbstract() && bcInfo.decoder == null) {
if (!isAbstract() && info.decoder == null) {
Assertions.UNREACHABLE("bad method " + getReference());
}
}
if (bcInfo.decoder == null) {
if (info.decoder == null) {
return;
}
bcInfo.pcMap = bcInfo.decoder.getInstructionsToBytecodes();
info.pcMap = info.decoder.getInstructionsToBytecodes();
processDebugInfo(bcInfo);
processDebugInfo(info);
SimpleVisitor simpleVisitor = new SimpleVisitor();
SimpleVisitor simpleVisitor = new SimpleVisitor(info);
Instruction[] instructions = bcInfo.decoder.getInstructions();
Instruction[] instructions = info.decoder.getInstructions();
for (int i = 0; i < instructions.length; i++) {
simpleVisitor.setInstructionIndex(i);
instructions[i].visit(simpleVisitor);
@ -487,65 +434,65 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
// copy the Set results into arrays; will use less
// storage
copyVisitorSetsToArrays(simpleVisitor);
copyVisitorSetsToArrays(simpleVisitor, info);
}
private void copyVisitorSetsToArrays(SimpleVisitor simpleVisitor) {
bcInfo.newSites = new NewSiteReference[simpleVisitor.newSites.size()];
private void copyVisitorSetsToArrays(SimpleVisitor simpleVisitor, BytecodeInfo info) {
info.newSites = new NewSiteReference[simpleVisitor.newSites.size()];
int i = 0;
for (Iterator<NewSiteReference> it = simpleVisitor.newSites.iterator(); it.hasNext();) {
bcInfo.newSites[i++] = it.next();
info.newSites[i++] = it.next();
}
bcInfo.fieldsRead = new FieldReference[simpleVisitor.fieldsRead.size()];
info.fieldsRead = new FieldReference[simpleVisitor.fieldsRead.size()];
i = 0;
for (Iterator<FieldReference> it = simpleVisitor.fieldsRead.iterator(); it.hasNext();) {
bcInfo.fieldsRead[i++] = it.next();
info.fieldsRead[i++] = it.next();
}
bcInfo.fieldsRead = new FieldReference[simpleVisitor.fieldsRead.size()];
info.fieldsRead = new FieldReference[simpleVisitor.fieldsRead.size()];
i = 0;
for (Iterator<FieldReference> it = simpleVisitor.fieldsRead.iterator(); it.hasNext();) {
bcInfo.fieldsRead[i++] = it.next();
info.fieldsRead[i++] = it.next();
}
bcInfo.fieldsWritten = new FieldReference[simpleVisitor.fieldsWritten.size()];
info.fieldsWritten = new FieldReference[simpleVisitor.fieldsWritten.size()];
i = 0;
for (Iterator<FieldReference> it = simpleVisitor.fieldsWritten.iterator(); it.hasNext();) {
bcInfo.fieldsWritten[i++] = it.next();
info.fieldsWritten[i++] = it.next();
}
bcInfo.callSites = new CallSiteReference[simpleVisitor.callSites.size()];
info.callSites = new CallSiteReference[simpleVisitor.callSites.size()];
i = 0;
for (Iterator<CallSiteReference> it = simpleVisitor.callSites.iterator(); it.hasNext();) {
bcInfo.callSites[i++] = it.next();
info.callSites[i++] = it.next();
}
bcInfo.arraysRead = new TypeReference[simpleVisitor.arraysRead.size()];
info.arraysRead = new TypeReference[simpleVisitor.arraysRead.size()];
i = 0;
for (Iterator<TypeReference> it = simpleVisitor.arraysRead.iterator(); it.hasNext();) {
bcInfo.arraysRead[i++] = it.next();
info.arraysRead[i++] = it.next();
}
bcInfo.arraysWritten = new TypeReference[simpleVisitor.arraysWritten.size()];
info.arraysWritten = new TypeReference[simpleVisitor.arraysWritten.size()];
i = 0;
for (Iterator<TypeReference> it = simpleVisitor.arraysWritten.iterator(); it.hasNext();) {
bcInfo.arraysWritten[i++] = it.next();
info.arraysWritten[i++] = it.next();
}
bcInfo.implicitExceptions = new TypeReference[simpleVisitor.implicitExceptions.size()];
info.implicitExceptions = new TypeReference[simpleVisitor.implicitExceptions.size()];
i = 0;
for (Iterator it = simpleVisitor.implicitExceptions.iterator(); it.hasNext();) {
bcInfo.implicitExceptions[i++] = (TypeReference) it.next();
info.implicitExceptions[i++] = (TypeReference) it.next();
}
bcInfo.castTypes = new TypeReference[simpleVisitor.castTypes.size()];
info.castTypes = new TypeReference[simpleVisitor.castTypes.size()];
i = 0;
for (Iterator<TypeReference> it = simpleVisitor.castTypes.iterator(); it.hasNext();) {
bcInfo.castTypes[i++] = it.next();
info.castTypes[i++] = it.next();
}
bcInfo.hasMonitorOp = simpleVisitor.hasMonitorOp;
info.hasMonitorOp = simpleVisitor.hasMonitorOp;
}
/**
@ -594,7 +541,18 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
return getReference().getDescriptor();
}
/**
*
* A visitor used to process bytecodes
*
*/
private class SimpleVisitor extends Instruction.Visitor {
private final BytecodeInfo info;
public SimpleVisitor(BytecodeInfo info) {
this.info = info;
}
// TODO: make a better Set implementation for these.
Set<CallSiteReference> callSites = HashSetFactory.make(5);
@ -622,13 +580,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
}
public int getProgramCounter() throws InvalidClassFileException {
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return bcInfo.pcMap[instructionIndex];
return info.pcMap[instructionIndex];
}
/*
@ -731,16 +683,10 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
* @throws InvalidClassFileException
*/
public Instruction[] getInstructions() throws InvalidClassFileException {
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
if (bcInfo.decoder == null) {
if (getBCInfo().decoder == null) {
return null;
} else {
return bcInfo.decoder.getInstructions();
return getBCInfo().decoder.getInstructions();
}
}
@ -751,16 +697,10 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
* @throws InvalidClassFileException
*/
public ExceptionHandler[][] getHandlers() throws InvalidClassFileException {
if (bcInfo == null) {
processBytecodes();
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
if (bcInfo.decoder == null) {
if (getBCInfo().decoder == null) {
return null;
} else {
return bcInfo.decoder.getHandlers();
return getBCInfo().decoder.getHandlers();
}
}
@ -806,23 +746,12 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
/**
* Clients should not modify the returned array. TODO: clone to avoid the
* problem?
* @throws InvalidClassFileException
*
* @see com.ibm.wala.classLoader.IMethod#getDeclaredExceptions()
*/
public TypeReference[] getDeclaredExceptions() {
if (bcInfo == null) {
try {
processBytecodes();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return (bcInfo.exceptionTypes == null) ? new TypeReference[0] : bcInfo.exceptionTypes;
public TypeReference[] getDeclaredExceptions() throws InvalidClassFileException {
return (getBCInfo().exceptionTypes == null) ? new TypeReference[0] : getBCInfo().exceptionTypes;
}
protected abstract String[] getDeclaredExceptionTypeNames() throws InvalidClassFileException;
@ -856,19 +785,8 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
*
* @see com.ibm.wala.classLoader.IMethod#getLineNumber(int)
*/
public int getLineNumber(int bcIndex) {
if (bcInfo == null) {
try {
processBytecodes();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
return (bcInfo.lineNumberMap == null) ? -1 : bcInfo.lineNumberMap[bcIndex];
public int getLineNumber(int bcIndex) throws InvalidClassFileException {
return (getBCInfo().lineNumberMap == null) ? -1 : getBCInfo().lineNumberMap[bcIndex];
}
/**
@ -919,7 +837,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
* @see com.ibm.wala.classLoader.IMethod#getLocalVariableName(int, int)
*/
public abstract String getLocalVariableName(int bcIndex, int localNumber);
public abstract String getLocalVariableName(int bcIndex, int localNumber) throws InvalidClassFileException;
/*
* TODO: cache for efficiency? (non-Javadoc)
@ -929,7 +847,7 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
public abstract boolean hasLocalVariableTable();
/**
* Clear all optional cached data associated with this class
* Clear all optional cached data associated with this class.
*/
public void clearCaches() {
bcInfo = null;

View File

@ -140,19 +140,8 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IMethod {
bcInfo.localVariableMap = LocalVariableTableReader.makeVarMap(cr);
}
public String getLocalVariableName(int bcIndex, int localNumber) {
if (bcInfo == null) {
try {
processBytecodes();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
}
if (Assertions.verifyAssertions) {
Assertions._assert(bcInfo != null);
}
int[][] map = bcInfo.localVariableMap;
public String getLocalVariableName(int bcIndex, int localNumber) throws InvalidClassFileException {
int[][] map = getBCInfo().localVariableMap;
if (localNumber > getMaxLocals()) {
throw new IllegalArgumentException("illegal local number: " + localNumber + ", method " + getName() + " uses at most "
@ -304,25 +293,19 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IMethod {
/**
* @return raw "Signature" attribute from the bytecode
* @throws InvalidClassFileException
*/
private String getGenericsSignature() {
if (bcInfo == null) {
try {
processBytecodes();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
}
return bcInfo.genericsSignature;
private String getGenericsSignature() throws InvalidClassFileException {
return getBCInfo().genericsSignature;
}
/**
* UNDER CONSTRUCTION
*
* @return
* @throws InvalidClassFileException
*/
public MethodTypeSignature getMethodTypeSignature() {
public MethodTypeSignature getMethodTypeSignature() throws InvalidClassFileException {
String sig = getGenericsSignature();
return sig == null ? null : MethodTypeSignature.make(sig);
}

View File

@ -56,14 +56,6 @@ public class ShrikeIRFactory implements IRFactory {
// This should be a method from Shrike
Assertions._assert(method instanceof ShrikeCTMethod);
// Set up some ShrikeCT mapping information before constructing SSA
try {
((ShrikeCTMethod) method).processBytecodes();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
com.ibm.wala.shrikeBT.Instruction[] shrikeInstructions;
try {
shrikeInstructions = ((ShrikeCTMethod) method).getInstructions();

View File

@ -13,6 +13,7 @@ package com.ibm.wala.classLoader;
import com.ibm.wala.cfg.InducedCFG;
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAOptions;
@ -282,7 +283,7 @@ public class SyntheticMethod implements IMethod {
*
* @see com.ibm.wala.classLoader.IMethod#getDeclaredExceptions()
*/
public TypeReference[] getDeclaredExceptions() {
public TypeReference[] getDeclaredExceptions() throws InvalidClassFileException {
if (resolvedMethod == null) {
return null;
} else {

View File

@ -72,6 +72,9 @@ public class TypeVariableSignature extends TypeSignature {
return -1;
}
FormalTypeParameter[] fp = sig.getFormalTypeParameters();
if (fp == null) {
return -1;
}
for (int i = 0; i < fp.length; i++) {
FormalTypeParameter f = fp[i];
if (f.getIdentifier().equals(v.getIdentifier())) {

View File

@ -22,6 +22,7 @@ import com.ibm.wala.shrikeBT.ConstantInstruction;
import com.ibm.wala.shrikeBT.Constants;
import com.ibm.wala.shrikeBT.Instruction;
import com.ibm.wala.shrikeBT.InvokeInstruction;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
@ -87,8 +88,14 @@ public class Exceptions implements Constants {
case OP_invokestatic:
case OP_invokeinterface:
InvokeInstruction call = (InvokeInstruction) pei;
Collection<TypeReference> result = inferInvokeExceptions(ShrikeUtil.makeMethodReference(loader, call.getClassType(), call.getMethodName(),
call.getMethodSignature()), cha, warnings);
Collection<TypeReference> result = null;
try {
result = inferInvokeExceptions(ShrikeUtil.makeMethodReference(loader, call.getClassType(), call.getMethodName(),
call.getMethodSignature()), cha, warnings);
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
return result;
case OP_athrow:
Assertions.UNREACHABLE("This class does not have the smarts to infer exception types for athrow");
@ -101,8 +108,9 @@ public class Exceptions implements Constants {
/**
* @return Colection<TypeReference>, set of exception types a call to a
* declared target might throw.
* @throws InvalidClassFileException
*/
public static Collection<TypeReference> inferInvokeExceptions(MethodReference target, ClassHierarchy cha, WarningSet warnings) {
public static Collection<TypeReference> inferInvokeExceptions(MethodReference target, ClassHierarchy cha, WarningSet warnings) throws InvalidClassFileException {
ArrayList<TypeReference> set = new ArrayList<TypeReference>(runtimeExceptions);
set.addAll(cha.getJavaLangErrorTypes());

View File

@ -32,6 +32,8 @@ import com.ibm.wala.ipa.cha.ClassHierarchy;
*
*/
public class ReferenceCleanser {
private final static float OCCUPANCY_TRIGGER = 0.5f;
private static WeakReference<ClassHierarchy> cha;
@ -68,6 +70,10 @@ public class ReferenceCleanser {
* A debugging aid. TODO: move this elsewhere
*/
public static void clearSoftCaches() {
float occupancy = 1f - ((float)Runtime.getRuntime().freeMemory() / (float)Runtime.getRuntime().totalMemory());
if (occupancy < OCCUPANCY_TRIGGER) {
return;
}
if (getAnalysisOptions() != null) {
getAnalysisOptions().getSSACache().wipe();
getAnalysisOptions().getCFGCache().wipe();