我正在开发一个项目,该项目将跟踪从包中的类到任何其他类的方法调用。重要的是我可以识别具体类型,并且我希望有一个最小的跟踪开销。触发探针的时间没有限制;它可以在调用方法之前或之后。
目前使用 ASM,但对它没有要求。该系统正在从 AspectJ 迁移,以允许动态连接,所以它已经过时了。
下面是目前的情况。'Tracer' 枚举/单例接收 probe(int) 并处理调用。找到从具体类型到引用类型的调用就足够了。
@Override
void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
Integer probeID = Tracer.INSTANCE.probes.createProbeIDAt(new Call(owner, name, desc))
super.visitFieldInsn(GETSTATIC, "org/flightofstairs/honours/capture/agent/Tracer", "INSTANCE", "Lorg/flightofstairs/honours/capture/agent/Tracer;");
super.visitLdcInsn(probeID)
super.visitMethodInsn(INVOKEVIRTUAL, "org/flightofstairs/honours/capture/agent/Tracer", "probe", "(Ljava/lang/Integer;)V")
super.visitMethodInsn(opcode, owner, name, desc);
}
我更进一步的想法是以某种方式获取对被调用类的引用并调用 getClass() 来检索具体类型。如果堆栈包含 INVOKEINTERFACE 顶部的对象引用,这将是微不足道的,但被调用方法的任何参数都放在它上面。
考虑到参数的数量是已知的,计算对象引用的堆栈位置不会有问题,但是 java 无法从堆栈中的较低位置复制引用。
有什么建议吗?
干杯。