/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: MetricsMethodVisitor.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.continuations.instrument;
import com.uwyn.rife.asm.*;
import com.uwyn.rife.continuations.ContinuationConfigInstrument;
import com.uwyn.rife.continuations.instrument.MetricsClassVisitor;
import com.uwyn.rife.continuations.instrument.NoOpAnnotationVisitor;
import java.util.ArrayList;
import java.util.HashMap;
class MetricsMethodVisitor implements MethodVisitor, Opcodes
{
private ContinuationConfigInstrument mConfig = null;
private MetricsClassVisitor mClassVisitor = null;
private String mClassName = null;
private int mPausecount = 0;
private int mAnswercount = 0;
private ArrayList<Label> mLabelsOrder = new ArrayList<Label>();
private HashMap<Label, String> mExceptionTypes = new HashMap<Label, String>();
private NoOpAnnotationVisitor mAnnotationVisitor = new NoOpAnnotationVisitor();
MetricsMethodVisitor(ContinuationConfigInstrument config, MetricsClassVisitor classVisitor, String className)
{
mConfig = config;
mClassVisitor = classVisitor;
mClassName = className;
}
public void visitMaxs(int maxStack, int maxLocals)
{
// go over all the labels in their order of appearance and check if
// they are exception labels with thus an initial exception
// type
ArrayList<String> exception_labels_types = new ArrayList<String>(mLabelsOrder.size());
for (Label label : mLabelsOrder)
{
exception_labels_types.add(mExceptionTypes.get(label));
}
// store all the metrics in the class visitor
mClassVisitor.setMaxLocals(maxLocals);
mClassVisitor.setPauseCount(mPausecount);
mClassVisitor.setAnswerCount(mAnswercount);
mClassVisitor.setExceptionTypes(exception_labels_types);
}
public void visitMethodInsn(int opcode, String owner, String methodname, String desc)
{
String owner_classname = owner.replace('/', '.');
if ((owner_classname.equals(mConfig.getContinuableSupportClassName()) || mClassName.equals(owner_classname)) &&
((mConfig.getPauseMethodName().equals(methodname) && "()V".equals(desc)) ||
(mConfig.getStepbackMethodName().equals(methodname) && "()V".equals(desc)) ||
(mConfig.getCallMethodName().equals(methodname) &&
Type.getMethodDescriptor(mConfig.getCallMethodReturnType(), mConfig.getCallMethodArgumentTypes()).equals(desc))))
{
mPausecount++;
}
else if (mConfig.getAnswerMethodName().equals(methodname) &&
("()V".equals(desc) || "(Ljava/lang/Object;)V".equals(desc)))
{
mAnswercount++;
}
}
public void visitFieldInsn(int opcode, String owner, String name, String desc)
{
}
public void visitVarInsn(int opcode, int var)
{
}
public void visitTryCatchBlock(Label start, Label end, Label handler, String type)
{
// store the types of the exception labels so that the exception
// instance can be cast to it when restoring the local
// variable stack
if (null == type)
{
type = "java/lang/Throwable";
}
mExceptionTypes.put(handler, type);
}
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)
{
}
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index)
{
}
public void visitJumpInsn(int opcode, Label label)
{
}
public void visitLabel(Label label)
{
// remember the order of the labels
mLabelsOrder.add(label);
}
public void visitMultiANewArrayInsn(String desc, int dims)
{
}
public void visitLineNumber(int line, Label start)
{
}
public void visitIntInsn(int opcode, int operand)
{
}
public void visitIincInsn(int var, int increment)
{
}
public void visitTypeInsn(int opcode, String desc)
{
}
public void visitLdcInsn(Object cst)
{
}
public void visitInsn(int opcode)
{
}
public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)
{
}
public void visitAttribute(Attribute attr)
{
}
public void visitCode()
{
}
public AnnotationVisitor visitAnnotationDefault()
{
return mAnnotationVisitor;
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
{
return mAnnotationVisitor;
}
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible)
{
return mAnnotationVisitor;
}
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack)
{
}
public void visitEnd()
{
}
}