SlowMethodAdapter.java 4.2 KB
Newer Older
J
modify:  
jackjintai 已提交
1
package com.didichuxing.doraemonkit.plugin.bytecode.method.slow;
J
modify:  
jackjintai 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;

/**
 * Created by jint on 13/12/2019. 生命周期
 * <p>
 * visitAnnotationDefault?
 * ( visitAnnotation | visitParameterAnnotation | visitAttribute )*
 * ( visitCode
 * ( visitTryCatchBlock | visitLabel | visitFrame | visitXxxInsn |
 * visitLocalVariable | visitLineNumber )*
 * visitMaxs )?
 * visitEnd
 */
public final class SlowMethodAdapter extends AdviceAdapter {
J
modify:  
jackjintai 已提交
19 20 21 22 23 24 25 26 27 28
    private String className;
    /**
     * 函数耗时阈值
     */
    private int thresholdTime;
    /**
     * 是否属于静态方法
     */
    private boolean isStaticMethod;

J
modify:  
jackjintai 已提交
29 30 31 32 33 34 35 36 37

    /**
     * Constructs a new {@link AdviceAdapter}.
     *
     * @param className     类名
     * @param thresholdTime 时间阈值
     * @param methodVisitor the method visitor to which this adapter delegates calls.
     * @param access        the method's access flags (see {@link Opcodes}).
     * @param methodName    the method's name.
J
modify:  
jackjintai 已提交
38
     * @param descriptor    the method's descriptor.
J
modify:  
jackjintai 已提交
39 40 41 42 43
     */
    public SlowMethodAdapter(MethodVisitor methodVisitor, String className, int thresholdTime, int access, String methodName, String descriptor) {
        super(Opcodes.ASM7, methodVisitor, access, methodName, descriptor);
        this.className = className;
        this.thresholdTime = thresholdTime;
J
modify:  
jackjintai 已提交
44
        //access值得计算方式为 Opcodes.ACC_PUBLIC & Opcodes.ACC_STATIC
J
modify:  
jackjintai 已提交
45
        this.isStaticMethod = (access & Opcodes.ACC_STATIC) != 0;
J
modify:  
jackjintai 已提交
46 47 48 49 50
    }

    @Override
    protected void onMethodEnter() {
        super.onMethodEnter();
J
modify:  
jackjintai 已提交
51
        try {
J
modify:  
jackjintai 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

            if (isStaticMethod) {
                //静态方法需要插入的代码
                mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false);
                mv.visitIntInsn(SIPUSH, thresholdTime);
                mv.visitLdcInsn(this.className + "&" + this.getName());
                mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostStart", "(ILjava/lang/String;)V", false);
            } else {
                //普通方法插入的代码
                mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false);
                mv.visitIntInsn(SIPUSH, thresholdTime);
                mv.visitLdcInsn(this.className + "&" + this.getName());
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostStart", "(ILjava/lang/String;Ljava/lang/Object;)V", false);
            }
J
modify:  
jackjintai 已提交
67
        } catch (Exception e) {
J
modify:  
jackjintai 已提交
68
            e.printStackTrace();
J
modify:  
jackjintai 已提交
69 70
        }

J
modify:  
jackjintai 已提交
71 72 73 74 75
    }

    @Override
    protected void onMethodExit(int opcode) {
        super.onMethodExit(opcode);
J
modify:  
jackjintai 已提交
76
        try {
J
modify:  
jackjintai 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90
            if (isStaticMethod) {
                //静态方法需要插入的代码
                mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false);
                mv.visitIntInsn(SIPUSH, thresholdTime);
                mv.visitLdcInsn(this.className + "&" + this.getName());
                mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostEnd", "(ILjava/lang/String;)V", false);
            } else {
                //普通方法插入的代码
                mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false);
                mv.visitIntInsn(SIPUSH, thresholdTime);
                mv.visitLdcInsn(this.className + "&" + this.getName());
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostEnd", "(ILjava/lang/String;Ljava/lang/Object;)V", false);
            }
J
modify:  
jackjintai 已提交
91
        } catch (Exception e) {
J
modify:  
jackjintai 已提交
92
            e.printStackTrace();
J
modify:  
jackjintai 已提交
93
        }
J
modify:  
jackjintai 已提交
94
    }
J
modify:  
jackjintai 已提交
95

J
modify:  
jackjintai 已提交
96
}