VerifyError:反向分支/ JVM规范4.10.2.4上存在未初始化的对象

 手机用户2502931235 发布于 2023-01-11 14:47

在JVM规格4.10.2.4版本7,最后一段说:

如果未初始化对象的特殊类型与除自身之外的特殊类型合并,则有效指令序列不得在操作数堆栈上或在向后分支的目标上的局部变量中具有未初始化对象

这是验证者拒绝的一个例子 - 我怀疑它应该被接受:

public scala.Tuple2 apply(boolean);
  flags: ACC_PUBLIC
  Code:
    stack=4, locals=2, args_size=2
       0: new           #12                 // class scala/Tuple2
       3: dup           
       4: aconst_null   
       5: iload_1       
       6: ifne          5
       9: aconst_null   
      10: invokespecial #16                 // Method scala/Tuple2."":(Ljava/lang/Object;Ljava/lang/Object;)V
      13: areturn       
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
             0      14     0  this   LC;
             0      14     1     x   Z
    StackMapTable: number_of_entries = 1
         frame_type = 255 /* full_frame */
        offset_delta = 5
        locals = [ class C, int ]
        stack = [ uninitialized 0, uninitialized 0, null ]

错误消息抱怨向后跳跃 ifne 5

java.lang.VerifyError: Uninitialized object exists on backward branch 5
Exception Details:
  Location:
    C.apply(Z)Lscala/Tuple2; @6: ifne

跳跃目标上的堆栈确实存在未初始化的对象; 然而,在我看来,"未初始化对象的特殊类型"与其自身合并,正如规范所要求的那样.

我认为只有一个堆栈映射框架,所以它不能与其他任何东西合并.

有趣的是,在JVM Spec版本8中删除了对向后分支的限制.

但是,Java 8 VM中的Verifier仍然拒绝该示例.

我是否误读了JVM规范,或者该示例是否真的未通过验证?我试过版本1.7.0_60-b191.8.0_05-b13.


一般研究

这个问题出现在Scala(bugreport)中.要重现,请使用scala 2.11.1,确保您使用的是JVM> = 1.7并运行以下命令(确保传递-target:jvm-1.7给scala):

localhost:sandbox luc$ scala -target:jvm-1.7
Welcome to Scala version 2.11.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_55).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class C {
     |   def apply(x: Boolean) = new Tuple2(null, {
     |     while (x) { }
     |     null
     |   })
     | }
defined class C

scala> new C
java.lang.VerifyError: Uninitialized object exists on backward branch 5
Exception Details:
  Location:
    C.apply(Z)Lscala/Tuple2; @6: ifne
  Reason:
    Error exists in the bytecode
  Bytecode:
    0000000: bb00 0959 011b 9aff ff01 b700 0db0
  Stackmap Table:
    full_frame(@5,{Object[#2],Integer},{Uninitialized[#0],Uninitialized[#0],Null})

  ... 32 elided

如上所述 - JDK bugreport在这里,我希望在那里得到回应.

JDK错误已在JDK 8u25中修复

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有