问题标签 [jvm-bytecode]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 根据执行历史记录,给定指令的操作数堆栈大小是否会有所不同?
例如,对于方法
javac
生成以下字节码:
在标签 4 处,堆栈具有相同的大小 (0),无论之前是哪条指令:3 或 16。
对于从 java 代码生成的字节码,这通常是正确的吗?
java - 在运行时移除 Java 常量池
我有以下Java类:
在这两个 if 语句中,结果都是错误的。当我为这个类输出常量池表时,我得到:
String_to_be_never_printed_2 存在 (#20),此时 String_to_be_never_printed_1 无处可见。这是预期的,因为编译器优化了第一个 if 语句。
我的问题是虚拟机是否会设法从常量池中删除 String_to_be_never_printed_2 (因为这永远不会被使用)?
java - JVM 规范中 JSR/RET 的状态
JVM 规范的某些部分表明操作JSR (Jump SubRoutine)、JSR_W (Jump SubRoutine Wide)和RET (RETurn from subroutine)只能在类文件版本 50.0 (JDK 1.6) 之前使用:
(本节假设编译器生成版本号为 50.0 或以下的类文件,因此可以使用 jsr 指令。另见§4.10.2.5。)
然后:
为了实现
try
-finally
构造,生成class
版本号为 50.0 或更低版本的文件的 Java 编程语言编译器可以使用异常处理工具以及两个特殊指令:jsr(“跳转到子程序”)和ret(“从子程序返回” ”)。
另一方面,操作码描述本身并没有说明这些功能的弃用。引用的文本仅说明了 50.0 之前的版本中的情况,但没有明确说明之后的情况。
此评论(询问有关弃用或删除背后动机的问题)表明类似程度的混乱,所以显然我不是唯一一个寻找这个的人。
java - AOT 仪表是什么意思?
我知道字节码检测是什么。它只是在运行时更改 .class 文件字节码,这似乎从 JDK 1.5 开始可用。但是,据说是在类加载期间而不是运行时。
现在我的问题是,什么是 AOT 或 Ahead of Time 仪器?什么是相反的程序?随着时间的推移仪表?
检测您的代码
Quasar 光纤依赖于字节码检测。这可以在类加载时通过 a 完成Java Agent
,或者在编译时使用 Ant 任务完成。运行 Instrumentation
Java AgentQuasar
的轻量级线程实现依赖于字节码检测。检测可以在编译时(下面详述)或在运行时使用 Java 代理执行。要运行 Java 代理,必须将以下内容添加到 java 命令行(或使用您喜欢的构建工具将其添加为 JVM 参数):
-javaagent:path-to-quasar-jar.jar
提前 (AOT)
检测 使用 Quasar 检测程序的简单且更可取的方法是使用 Java 代理,它在运行时检测代码。然而,有时,运行 Java 代理不是一种选择。Quasar 通过 Ant 任务支持 AOT 检测。该任务位于
co.paralleluniverse.fibers.instrument.InstrumentationTask
中quasar-core.jar
,它接受要检测的类文件集。并不是所有的类都会被实际检测——只有那些带有suspendable method
s 的类(见下文)——所以只需将程序中的所有类文件都交给任务。事实上,Quasar 本身已经 提前进行了检测。
java - 检索存储在类中的字段作为字节数组
我正在试验 ASM 库。
我有一个存储为 的类byte[]
,即以 CAFEBABE 开头,带有常量池等。
我想以尽可能方便的方式加载这个类并提取一个字段,因为这个过程将被添加到 ASM 的方法中。
有没有一种简单的方法可以将字节数组作为类加载而不会弄乱自定义类加载器等?
java - 将 InsnList 拆分为基本块
在 ASM Tree API 中,我有一个 InsnList,其中包含方法中的指令列表。
我想将其分解为基本块:一系列指令,使得除了最后一条指令之外的每条指令都有一个后继指令,并且除了第一条指令之外的任何指令都不能成为跳转的目标。
我将如何做到这一点?
algorithm - 如何确保命名参数列表的评估顺序和形式参数顺序?
在编译器上工作时,我面临与命名参数列表和评估顺序相关的问题。基本上,该语言确保对于以下函数和函数调用:
输出将是
尽管参数以相反的顺序给出。我正在研究 JVM,因此必须在字节码级别对它们进行排序以匹配call
. 在基于堆栈的伪字节码中:
正如你所看到的,swap
这里需要一个字节码指令来确保它们都被评估并以正确的顺序传递。这可以绘制为图表:
只有一条swap
指令可以交换堆栈顶部的两个元素,因此对于更多元素,编译器需要生成局部变量。
在字节码中:
当然,这可以扩展到任意数量的实际和形式参数。
我现在正在寻找的是某种算法,它确定我是否应该以及在哪里插入这些swap
或局部变量指令。对编译器实现的引用也会有所帮助。
请注意,哪个实际参数属于哪个形式参数不是我的问题的一部分。我的编译器已经解决了这个问题。为简化起见,可以这样看待问题:
给定两个大小相同的数组,其中包含不同顺序的相同元素,哪些元素可以从第一个数组交换或移动以获得第二个数组的顺序。
java - 如何在 ASM 中获取引用?
总结:使用 ASM,给定一个字节码类,对于每个方法指令(MethodInsnNode),我需要获取正在使用的引用。
考虑以下类:
}
考虑以下生成的字节码指令:
我试图找出一种方法来获取使用 ASM 调用的对象引用。在字节码级别,每次INVOKESPECIAL
调用指令时,它都会加载之前将使用的值。例如:
所以那里有它的参考。但是在 ASM 中,没有提到this
. 确切的堆栈跟踪将像这样,它由包含“prev”属性的实际指令组成,该属性将是已被调用以加载该变量的方法:
问题是我们有所有者属性,名称属性,但我无法获得对该对象的引用。在以下情况下:
我需要在 ASM 中引用“cemo”对象。
到目前为止我已经尝试过: - 获取框架对象,但它只包含变量“插槽”,没有引用。- 分析MethodInsnNode
前面的指令。
我应该如何做到这一点?
java - ByteBuddy:java.lang.IllegalArgumentException:无法附加未定义的变量:V
当com.google.common.collect.ImmutableMultimap$Values
从 Google Guava 重新定义类时,我从 ByteBuddy 得到一个 IllegalArgumentException。
内部类是com.google.common.collect.ImmutableCollection
其方法ImmutableList<E> createAsList()
导致问题的子类。
堆栈跟踪:
我在这里创建了一个触发问题的示例:https ://github.com/erikhakansson/bytebuddytest 该测试是根据我之前的测试修改的,因此那里可能有一些垃圾。
要进行测试,只需运行 mvn clean install 然后运行生成的 jar。
很可能,我做错了什么,但我不知道是什么,所以请帮忙!:)