how to create a local variable at the begin of the method when modify it
i want to add a monitor for a method to calculate execution time, but i found that the variable I created were overwritten. the local variable start has been overwritten by a local variable in the method before. I want to know how to create a local variable at the begin of the method when modify it. The details are as follows: there is a method:
private int count;
public void setCount(int count, long e) {
Long a1 = 101L;
Long a3 = 103L;
try {
try {
Long a4 = 104L;
this.count = count;
int a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 4;
System.out.println(a + b + c + d + e);
} catch (RuntimeException e1) {
throw e1;
} finally {
System.out.println("finally");
}
} catch (RuntimeException r) {
throw r;
} finally {
System.out.println("finally2");
}
}
I want it to be like this:
private int count;
public void setCount(int count, long e) {
Long start = BistourySpys1.start();
try {
Long a1 = 101L;
Long a3 = 103L;
try {
try {
Long a4 = 104L;
this.count = count;
int a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 4;
System.out.println(a + b + c + d + e);
} catch (RuntimeException e1) {
throw e1;
} finally {
System.out.println("finally");
}
} catch (RuntimeException r) {
throw r;
} finally {
System.out.println("finally2");
}
BistourySpys1.stop("key", start);
} catch (Throwable t) {
BistourySpys1.stop("key", start);
BistourySpys1.exception("key");
throw t;
}
}
and I create a methodVisitor like this
public class MonitorAdviceAdapter extends AdviceAdapter {
private final String MONITOR_KEY;
private final Type[] parameterTypes;
private final Type returnType;
private final boolean hasReturn;
private final String desc;
private final String className;
private final String methodName;
private final int totalParameterSize;
private final int startOfVarIndex;
private final int scopeVarIndex;
private final Type SPY_TYPE = Type.getType(BistourySpys1.class);
private final Method start = new Method("start", Type.getMethodDescriptor(Type.getType(Long.class)));
private final Method stop = new Method("stop", Type.getMethodDescriptor(Type.getType(void.class), Type.getType(String.class), Type.getType(Long.class)));
private final Method exception = new Method("exception", Type.getMethodDescriptor(Type.getType(void.class), Type.getType(String.class)));
private static final String THROWABLE_EXCEPTION = Type.getInternalName(Throwable.class);
protected MonitorAdviceAdapter(int api, MethodVisitor methodVisitor, int access, String name, String desc, String className, String[] exceptions) {
super(ASM7, methodVisitor, access, name, desc);
this.className = className;
this.methodName = name;
this.desc = desc;
this.MONITOR_KEY = "key"
this.returnType = Type.getReturnType(desc);
this.hasReturn = this.returnType != Type.VOID_TYPE;
this.parameterTypes = Type.getArgumentTypes(desc);
this.totalParameterSize = computeTotalParameterSize(parameterTypes);
this.startOfVarIndex = Access.of(access).contain(Opcodes.ACC_STATIC) ? 0 : 1;
scopeVarIndex = startOfVarIndex + totalParameterSize;
beginLabel = new Label();
endLabel = new Label();
throwableLabel = new Label();
}
private Label beginLabel;
private Label endLabel;
private Label throwableLabel;
private Label startLocal;
private Label endLoacl;
@Override
protected void onMethodEnter() {
//catch
super.visitTryCatchBlock(beginLabel, endLabel, throwableLabel, THROWABLE_EXCEPTION);
startLocal = mark();
startMonitor(scopeVarIndex);
endLoacl = mark();
mark(beginLabel);
}
@Override
protected void onMethodExit(int opcode) {
//正常返回结束
if (opcode == RETURN || opcode == IRETURN || opcode == FRETURN || opcode == ARETURN || opcode == LRETURN || opcode == DRETURN) {
endMonitor(scopeVarIndex);
}
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
mark(endLabel);
emitCatchBlocks(scopeVarIndex);
int computeMaxLocals = computeMaxLocals();
super.visitMaxs(Math.max(maxStack, Math.max(computeMaxLocals, 4)), computeMaxLocals);
}
private void emitCatchBlocks(int scopeVarIndex) {
//catch blocks
super.visitLabel(throwableLabel);
//ex
int exceptionVarIndex = scopeVarIndex + 1;
super.visitVarInsn(ASTORE, exceptionVarIndex);
exceptionMonitor();
//异常处理中结束
endMonitor(scopeVarIndex);
//throw ex
super.visitVarInsn(ALOAD, exceptionVarIndex);
super.visitInsn(ATHROW);
}
private void startMonitor(int scopeVarIndex) {
//long startTime=AgentMonitor.start();
invokeStatic(SPY_TYPE, start);
super.visitVarInsn(ASTORE, scopeVarIndex);
}
private void endMonitor(int scopeVarIndex) {
//AgentMonitor.stop(key,startTime);
push(MONITOR_KEY);
super.visitVarInsn(ALOAD, scopeVarIndex);
invokeStatic(SPY_TYPE, stop);
}
private void exceptionMonitor() {
push(MONITOR_KEY);
invokeStatic(SPY_TYPE, exception);
}
private int computeTotalParameterSize(Type[] parameterTypes) {
int result = 0;
int parameterCount = parameterTypes.length;
for (int i = 0; i < parameterCount; i++) {
result += parameterTypes[i].getSize();
}
return result;
}
private int computeMaxLocals() {
return startOfVarIndex + totalParameterSize + 1 + (hasReturn ? returnType.getSize() : 1);
}
}
I found that the variable I created were overwritten. the local variable start has been overwritten by a1
public void setCount(int count, long e) {
Long a1 = BistourySpys1.start();
try {
a1 = 101L;
Long var5 = 103L;
try {
try {
Long a4 = 104L;
this.count = count;
int a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 4;
System.out.println((long)(a + b + c + d) + e);
} catch (RuntimeException var23) {
throw var23;
} finally {
System.out.println("finally");
}
} catch (RuntimeException var25) {
throw var25;
} finally {
System.out.println("finally2");
}
BistourySpys1.stop("qunar.tc.test.Test#setCount(int,long)", a1);
} catch (Throwable var27) {
BistourySpys1.exception("qunar.tc.test.Test#setCount(int,long)");
BistourySpys1.stop("qunar.tc.test.Test#setCount(int,long)", a1);
throw var27;
}
}
Thanks.