您的位置:首页 > 其它

这样的错误竟然能得到正确的值,这个bug藏的够深的。

2011-05-08 18:32 429 查看
为了统计方法执行时候,我用ASM在方法开始的时候插入一个变量startLocal记录开始执行的时间,然后在结束的时间用当前时间去差这个开始时间,为了调试,我同时又插入了一个endLocal

/**
 * Project: dragoon-common-2.5.3
 * 
 * File Created at 2011-5-5
 * $Id$
 * 
 * Copyright 1999-2100 Alibaba.com Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Alibaba Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Alibaba.com.
 */
package com.alibaba.instrumention.classop;
import com.alibaba.citrus.asm.MethodVisitor;
import com.alibaba.citrus.asm.Opcodes;
import com.alibaba.citrus.asm.Type;
import com.alibaba.citrus.asm.commons.AdviceAdapter;
/**
 * Comment of InstrumtionAdviceAdapter
 * 
 * @author axman.wang
 */
public class InstrumentionAdviceAdapter extends AdviceAdapter {
    private String methodName;
    //private int access;  
    private String className;
    private int    startLocal;

    protected InstrumentionAdviceAdapter(MethodVisitor mv, int access, String methodName,
                                       String desc, String signature, String[] exceptions,String className) {
        super(mv, access, methodName, desc);
        this.methodName = methodName;
        //this.access = access;  
        this.className = className;
    }
    protected void onMethodEnter() {
        this.mv.visitLdcInsn(className + "." + methodName);
        this.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/alibaba/instrumention/classop/InstrumentionStat", "before",
                "(Ljava/lang/String;)V");
        
        this.startLocal = this.newLocal(Type.getType(Long.class));
        this.mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J");
        this.mv.visitVarInsn(LSTORE, startLocal);
    }
    protected void onMethodExit(int opcode) {
        
        this.mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J");
        this.mv.visitVarInsn(LLOAD, startLocal);        
        this.mv.visitInsn(LSUB);               
        this.mv.visitLdcInsn(className + "." + methodName);
        this.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/alibaba/instrumention/classop/InstrumentionStat", "after",
                "(JLjava/lang/String;)V");
    }
}


却得不到正确的结果了。于是反复查看地,终于发现了
this.startLocal = this.newLocal(Type.getType(Long.class));
应该是:
this.startLocal = this.newLocal(Type.LONG_TYPE);
如果开始分配的栈不对,两个object的栈相当于一个long的栈,但在LSUB的时候为什么是正确的?
两个Long对象进行lsub,虽然java源码在编译的时候可以自动插入转换指令,但在上面的字节码指令中
仍然可以正确LSUB,虽然栈中的值是正确的,但却越过了类型检查。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐