001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: MetricsMethodVisitor.java 3805 2007-06-23 20:18:19Z gbevin $
007: */
008: package com.uwyn.rife.continuations.instrument;
009:
010: import com.uwyn.rife.asm.*;
011:
012: import com.uwyn.rife.continuations.ContinuationConfigInstrument;
013: import com.uwyn.rife.continuations.instrument.MetricsClassVisitor;
014: import com.uwyn.rife.continuations.instrument.NoOpAnnotationVisitor;
015: import java.util.ArrayList;
016: import java.util.HashMap;
017:
018: class MetricsMethodVisitor implements MethodVisitor, Opcodes {
019: private ContinuationConfigInstrument mConfig = null;
020: private MetricsClassVisitor mClassVisitor = null;
021: private String mClassName = null;
022: private int mPausecount = 0;
023: private int mAnswercount = 0;
024: private ArrayList<Label> mLabelsOrder = new ArrayList<Label>();
025: private HashMap<Label, String> mExceptionTypes = new HashMap<Label, String>();
026: private NoOpAnnotationVisitor mAnnotationVisitor = new NoOpAnnotationVisitor();
027:
028: MetricsMethodVisitor(ContinuationConfigInstrument config,
029: MetricsClassVisitor classVisitor, String className) {
030: mConfig = config;
031: mClassVisitor = classVisitor;
032: mClassName = className;
033: }
034:
035: public void visitMaxs(int maxStack, int maxLocals) {
036: // go over all the labels in their order of appearance and check if
037: // they are exception labels with thus an initial exception
038: // type
039: ArrayList<String> exception_labels_types = new ArrayList<String>(
040: mLabelsOrder.size());
041: for (Label label : mLabelsOrder) {
042: exception_labels_types.add(mExceptionTypes.get(label));
043: }
044:
045: // store all the metrics in the class visitor
046: mClassVisitor.setMaxLocals(maxLocals);
047: mClassVisitor.setPauseCount(mPausecount);
048: mClassVisitor.setAnswerCount(mAnswercount);
049: mClassVisitor.setExceptionTypes(exception_labels_types);
050: }
051:
052: public void visitMethodInsn(int opcode, String owner,
053: String methodname, String desc) {
054: String owner_classname = owner.replace('/', '.');
055:
056: if ((owner_classname.equals(mConfig
057: .getContinuableSupportClassName()) || mClassName
058: .equals(owner_classname))
059: && ((mConfig.getPauseMethodName().equals(methodname) && "()V"
060: .equals(desc))
061: || (mConfig.getStepbackMethodName().equals(
062: methodname) && "()V".equals(desc)) || (mConfig
063: .getCallMethodName().equals(methodname) && Type
064: .getMethodDescriptor(
065: mConfig.getCallMethodReturnType(),
066: mConfig.getCallMethodArgumentTypes())
067: .equals(desc)))) {
068: mPausecount++;
069: } else if (mConfig.getAnswerMethodName().equals(methodname)
070: && ("()V".equals(desc) || "(Ljava/lang/Object;)V"
071: .equals(desc))) {
072: mAnswercount++;
073: }
074: }
075:
076: public void visitFieldInsn(int opcode, String owner, String name,
077: String desc) {
078: }
079:
080: public void visitVarInsn(int opcode, int var) {
081: }
082:
083: public void visitTryCatchBlock(Label start, Label end,
084: Label handler, String type) {
085: // store the types of the exception labels so that the exception
086: // instance can be cast to it when restoring the local
087: // variable stack
088: if (null == type) {
089: type = "java/lang/Throwable";
090: }
091:
092: mExceptionTypes.put(handler, type);
093: }
094:
095: public void visitLookupSwitchInsn(Label dflt, int[] keys,
096: Label[] labels) {
097: }
098:
099: public void visitLocalVariable(String name, String desc,
100: String signature, Label start, Label end, int index) {
101: }
102:
103: public void visitJumpInsn(int opcode, Label label) {
104: }
105:
106: public void visitLabel(Label label) {
107: // remember the order of the labels
108: mLabelsOrder.add(label);
109: }
110:
111: public void visitMultiANewArrayInsn(String desc, int dims) {
112: }
113:
114: public void visitLineNumber(int line, Label start) {
115: }
116:
117: public void visitIntInsn(int opcode, int operand) {
118: }
119:
120: public void visitIincInsn(int var, int increment) {
121: }
122:
123: public void visitTypeInsn(int opcode, String desc) {
124: }
125:
126: public void visitLdcInsn(Object cst) {
127: }
128:
129: public void visitInsn(int opcode) {
130: }
131:
132: public void visitTableSwitchInsn(int min, int max, Label dflt,
133: Label[] labels) {
134: }
135:
136: public void visitAttribute(Attribute attr) {
137: }
138:
139: public void visitCode() {
140: }
141:
142: public AnnotationVisitor visitAnnotationDefault() {
143: return mAnnotationVisitor;
144: }
145:
146: public AnnotationVisitor visitAnnotation(String desc,
147: boolean visible) {
148: return mAnnotationVisitor;
149: }
150:
151: public AnnotationVisitor visitParameterAnnotation(int parameter,
152: String desc, boolean visible) {
153: return mAnnotationVisitor;
154: }
155:
156: public void visitEnd() {
157: }
158: }
|