* .classfile.IAnalysisCache, java.lang.Object)
*/
@Override
public CFG analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException {
// Construct the CFG in its raw form
MethodGen methodGen = analysisCache.getMethodAnalysis(MethodGen.class, descriptor);
if (methodGen == null) {
JavaClass jclass = analysisCache.getClassAnalysis(JavaClass.class, descriptor.getClassDescriptor());
Method method = analysisCache.getMethodAnalysis(Method.class, descriptor);
JavaClassAndMethod javaClassAndMethod = new JavaClassAndMethod(jclass, method);
AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportSkippedAnalysis(descriptor);
throw new MethodUnprofitableException(javaClassAndMethod);
}
CFGBuilder cfgBuilder = CFGBuilderFactory.create(descriptor, methodGen);
cfgBuilder.build();
CFG cfg = cfgBuilder.getCFG();
// Mark as busy while we're pruning the CFG.
cfg.setFlag(CFG.BUSY);
// Important: eagerly put the CFG in the analysis cache.
// Recursively performed analyses required to prune the CFG,
// such as TypeAnalysis, will operate on the raw CFG.
analysisCache.eagerlyPutMethodAnalysis(CFG.class, descriptor, cfg);
// Record method name and signature for informational purposes
cfg.setMethodName(SignatureConverter.convertMethodSignature(methodGen));
cfg.setMethodGen(methodGen);
// System.out.println("CC: getting refined CFG for " + methodId);
if (CFGFactory.DEBUG_CFG) {
String methodId = methodGen.getClassName() + "." + methodGen.getName() + ":" + methodGen.getSignature();
System.out.println("CC: getting refined CFG for " + methodId);
}
if (ClassContext.DEBUG) {
String methodId = methodGen.getClassName() + "." + methodGen.getName() + ":" + methodGen.getSignature();
System.out.println("ClassContext: request to prune " + methodId);
}
// Remove CFG edges corresponding to failed assertions.
boolean changed = false;
boolean ASSUME_ASSERTIONS_ENABLED = true;
if (ASSUME_ASSERTIONS_ENABLED) {
LinkedList<Edge> edgesToRemove = new LinkedList<Edge>();
for (Iterator<Edge> i = cfg.edgeIterator(); i.hasNext();) {
Edge e = i.next();
if (e.getType() == EdgeTypes.IFCMP_EDGE) {
try {
BasicBlock source = e.getSource();
InstructionHandle last = source.getLastInstruction();
Instruction lastInstruction = last.getInstruction();
InstructionHandle prev = last.getPrev();
Instruction prevInstruction = prev.getInstruction();
if (prevInstruction instanceof GETSTATIC && lastInstruction instanceof IFNE) {
GETSTATIC getStatic = (GETSTATIC) prevInstruction;
if (getStatic.getFieldName(methodGen.getConstantPool()).equals("$assertionsDisabled")
&& getStatic.getSignature(methodGen.getConstantPool()).equals("Z")) {
edgesToRemove.add(e);
}
}
} catch (RuntimeException exception) {
assert true; // ignore it