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:
parent
9f2055ac93
commit
2870d1dbc8
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue