【问题标题】:Status of JSR/RET in JVM specJVM 规范中 JSR/RET 的状态
【发布时间】:2016-08-29 01:36:29
【问题描述】:

JVM 规范的某些部分建议操作JSR (Jump SubRoutine)JSR_W (Jump SubRoutine Wide)RET (RETurn from subroutine) 只能在类文件版本 50.0 (JDK 1.6) 之前使用:

3.13 Compiling Finally

(本节假设编译器生成版本号为 50.0 或以下的类文件,因此可以使用 jsr 指令。另见§4.10.2.5。)

后来:

4.10.2.5. Exceptions and finally

为了实现try-finally 构造,Java 编程语言的编译器生成版本号为 50.0 或更低版本的class 文件可以使用异常处理工具和两条特殊指令: jsr(“跳转到子程序”)和ret(“从子程序返回”)。

另一方面,操作码描述本身并没有说明这些功能的弃用。引用的文字只说明了 50.0 之前的版本,但没有明确说明之后的情况。

This comment(询问有关弃用或删除背后动机的问题)表示类似程度的混乱,所以显然我不是唯一一个在寻找这个的人。

【问题讨论】:

    标签: java jvm opcode finally jvm-bytecode


    【解决方案1】:

    在为我的问题添加链接时,我注意到§4.10.1.9: Type Checking Instructions 中没有相关操作码。所以这说明新的基于 strackframe 的类型验证方案无法处理它们,§4.10: Verification of class Files 写道:

    必须使用类型检查验证来验证版本号大于或等于 50.0 的 class 文件。

    或者更详细的§4.10.1: Verification by Type Checking

    必须使用本节中给出的类型检查规则来验证版本号为 50.0 或更高版本 (§4.1) 的 class 文件。

    当且仅当 class 文件的版本号等于 50.0 时,如果类型检查失败,Java 虚拟机实现可能会选择尝试通过类型推断 (§4.10.2) 执行验证。

    所以我会说 50.0 版本的类 可能 仍然包含 jsrret,但存在 JVM 实现无法实现的风险' t 验证所述类,因此将无法加载它。

    但后来我发现了一个更明确的规则,在§4.9.1: Static Constraints

    只有§6.5 中记录的指令实例可能会出现在code 数组中。使用保留操作码 (§6.2) 或本规范中未记录的任何操作码的指令实例不得出现在 code 数组中。

    如果class文件版本号为51.0或以上,那么jsr操作码和jsr_w操作码都不能出现在code数组中。 p>

    第一段与此问题无关,因为说明在 §6.5 中列出,并且根据 §6.2 未保留。但是第二段明确地将它们标记为在 51.0 及更高版本中被禁止。另一方面,ret 操作码在没有 jsrjsr_w 的情况下是无用的,因为只有这两条指令可以创建 @ 类型的堆栈元素987654340@ (并通过一些 astore 该类型的局部变量)供 ret 使用。


    我仍然认为应该在 §6.5 中包含一些关于此效果的通知。不幸的是,Java bug report webpage 隐藏了 Continue 按钮,如果选择类型:Bug,类别:Java 平台标准版,子类别:规范。它指出

    此子类别用于报告 Java 语言规范和 JVM 规范文本中的技术错误和歧义。它不是提出 Java 语言或 JVM 新特性的场所。正在进行的功能开发在OpenJDK 中进行;通过Java Community Process 管理对Java 语言规范和JVM 规范的相应增强。

    但是通过 JCP 只是为了在这三个操作码的描述中添加一些澄清说明,感觉就像是大材小用。所以我希望这篇文章能帮助那些靠自己无法在规范本身中找到答案的人。

    【讨论】:

    • 干得好!我曾经向 Java 报告了一个功能请求(stackoverflow.com/questions/31056219/…,授予,可能在错误的地方...),未经 Oracle 批准,它甚至不会出现在公共 URL 上,这从未发生过... :-/ 就像 Android 一样,我们必须接受 Java 的本来面目,这是来自上帝的半完美礼物。
    • 另外,即使在类型检查说明中提到了jsr,仍然无法使用新的基于堆栈帧的验证来处理它们,因为每个分支目标需要 i> 显式堆栈帧,但堆栈帧无法在帧中表示 返回地址 类型。
    猜你喜欢
    • 2011-01-18
    • 2015-04-29
    • 2023-04-05
    • 1970-01-01
    • 2020-07-26
    • 2016-10-28
    • 2018-10-30
    • 2015-03-05
    • 1970-01-01
    相关资源
    最近更新 更多