我想知道是否可以使用 ASM API 跟踪对数组的访问。
我的目标是确定访问数组的哪个索引,以及何时访问(这部分很容易 - 使用System.NanoTime()
)。我只是找不到确定正在访问哪个索引的方法。
我一直在尝试使用以下那些没有任何成功 - visitFieldInsn
(对于类的静态和非静态变量),visitVarInsn
(对于静态和非静态局部变量),以及visitMultiANewArrayInsn
- 它并没有真正识别任何数组。
我想知道是否可以使用 ASM API 跟踪对数组的访问。
我的目标是确定访问数组的哪个索引,以及何时访问(这部分很容易 - 使用System.NanoTime()
)。我只是找不到确定正在访问哪个索引的方法。
我一直在尝试使用以下那些没有任何成功 - visitFieldInsn
(对于类的静态和非静态变量),visitVarInsn
(对于静态和非静态局部变量),以及visitMultiANewArrayInsn
- 它并没有真正识别任何数组。
特定索引不是指令的一部分。您必须查看操作数堆栈顶部的值以找出指令所指的索引。请参阅JVM 参考资料。
但是,您不想破坏操作数堆栈,因此当您遇到数组访问指令时,请执行DUP
do 复制堆栈顶部(复制指令引用的索引),然后打印该值或执行任何您喜欢的操作使用它,然后继续访问原始说明。
但是,您应该知道访问数组有多种不同的指令:
aaload
, iaload
, laload
, saload
, baload
,caload
和daload
用于阅读,和aastore
, iastore
, lastore
, sastore
, bastore
,castore
和dastore
写作值得注意的是, nanoTime() 需要大约 100 倍的时间来访问数组本身。这可能会严重扭曲结果。
您是否尝试过使用 ASMifier 查看您的代码。这应该向您显示您的代码触发了哪些事件。
顺便说一句,您可以用方法调用替换数组查找,例如
public static int arrayGet(int[] int.int index)
这将允许您在访问 int[] 时放入 Java 中您希望它执行的任何操作。