使用ASM访问数组
我想知道是否可以使用 ASM API 跟踪对数组的访问。
我的目标是确定访问数组的哪个索引以及何时访问(这部分很简单 - 使用 System.NanoTime() )。我只是找不到一种方法来确定正在访问哪个索引。
我一直在尝试使用以下内容,但没有成功 - visitFieldInsn
(对于类的静态和非静态变量),visitVarInsn
(对于静态和非静态局部变量),以及visitMultiANewArrayInsn
- 它没有真正识别任何数组。
I'd like to know if it's possible to trace access to an array using ASM API.
My goal is to determine which index of an array is accessed, and when (this part is easy - using System.NanoTime()
). I just couldn't find a way to determine which index is being accessed.
I have been trying to use those following without any success - visitFieldInsn
(for static and non static vars of a class ), visitVarInsn
( for static and nonstatic local variables ), and visitMultiANewArrayInsn
- which didn't really recognize any array.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
特定索引不是指令的一部分。您必须查看操作数堆栈顶部的值才能找出指令引用的索引。请参阅 JVM 参考。
但是,您不想破坏操作数堆栈,因此当您遇到数组访问指令时,请执行 DUP 复制堆栈顶部(复制指令引用的索引),然后打印该值或对其进行任何您喜欢的操作,然后继续访问原始说明。
然而,您应该知道有多种不同的指令可以访问数组:
aaload
、iaload
、laload
、saload
、baload
、caload
和daload
用于读取,以及aastore
、iastore
、<用于写入的 code>lastore、sastore
、bastore
、castore
和dastore
The particular index is not part of the instruction. You have to peek at the value at top of the operand stack to find out which index the instruction refers to. See the JVM reference.
You don't want to havoc the operand stack however, so when you encounter an array-access instruction, perform a
DUP
do duplicate the top of the stack (duplicate the index the instruction refers to) and then print the value or do whatever you like with it and then continue by visiting the original instruction.You should know however that there are multiple different instructions to access an array:
aaload
,iaload
,laload
,saload
,baload
,caload
anddaload
for reading, andaastore
,iastore
,lastore
,sastore
,bastore
,castore
anddastore
for writing值得注意的是,nanoTime() 花费的时间大约是数组访问自身的 100 倍。这可能会严重影响结果。
您是否尝试过使用 ASMifier 查看您的代码?这应该显示您的代码触发了哪些事件。
顺便说一句,你可以用方法调用替换数组查找,例如
public static int arrayGet(int[] int.int index)
这将允许你在访问 int[] 时将你想要做的任何事情放入 Java 中。
Its worth noting that nanoTime() takes about 100x long that the array access itself. This could significatly skew results.
Have you tried looking at your code with the ASMifier. This should show you what events are triggered by you code.
BTW you can replace the array lookups with method calls e.g.
public static int arrayGet(int[] int. int index)
This will allow you to put in Java whatever you want it to do when an int[] is accessed.