5 MethodInstrumenter
- 这个方法适配器根据 MethodProbesVisitor 事件的请求插入探针。
6 MethodSanitizer
此 method visitor 修复了Java字节码的两个潜在问题:
- 通过内联从Java 6开始不推荐使用的子例程来删除JSR / RET指令。RET语句使控制流分析变得复杂,因为未明确给出跳转目标
- 如果代码属性的行号和局部变量名称指向某些工具创建的无效偏移量,则将其删除。 用ASM类文件写出此类无效标签时,请勿再进行验证
class MethodSanitizer extends JSRInlinerAdapter { MethodSanitizer(final MethodVisitor mv, final int access, final String name, final String desc, final String signature, final String[] exceptions) { super(InstrSupport.ASM_API_VERSION, mv, access, name, desc, signature, exceptions); } @Override public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int index) { // Here we rely on the usage of the info fields by the tree API. If the // labels have been properly used before the info field contains a // reference to the LabelNode, otherwise null. if (start.info != null && end.info != null) { super.visitLocalVariable(name, desc, signature, start, end, index); } } @Override public void visitLineNumber(final int line, final Label start) { // Here we rely on the usage of the info fields by the tree API. If the // labels have been properly used before the info field contains a // reference to the LabelNode, otherwise null. if (start.info != null) { super.visitLineNumber(line, start); } } }
LabelInfo
附加到 Label#info 对象的数据容器,用于存储 flow 和特定 instrumentation 的信息。 该信息仅在特定情况下在本地有效。
属性
/** * Reserved ID for "no probe". */ public static final int NO_PROBE = -1; private boolean target = false; private boolean multiTarget = false; private boolean successor = false; private boolean methodInvocationLine = false; private boolean done = false; private int probeid = NO_PROBE; private Label intermediate = null; private Instruction instruction = null;
API
/** * 确定给定标签是否需要在其之前插入探针。 * * @param label label to test * @return true if a probe should be inserted before */ public static boolean needsProbe(final Label label) { final LabelInfo info = get(label); return info != null && info.successor && (info.multiTarget || info.methodInvocationLine); }