HotSpot and IBM's J9 behave a little different when verifying this class

Yuting Chen chenyt.cs.sjtu at gmail.com
Thu Apr 13 21:48:59 UTC 2017


I recently found an interesting class. Hope that I can get answers here.

The bytecode is shown as follows. Hotspot can catch some
inconsistencies here (Reason: Current frame's flags are not assignable
to stack map frame's), while J9 cannot.

I thought J9 was wrong until I went into HotSpot's source code and saw
some comments in share/vm/classfile/verifier.cpp.  It says that the
verifier "Return TRUE if all code paths starting with start_bc_offset
end in bytecode athrow or loop" (a comment before bool
ClassVerifier::ends_in_athrow(u4 start_bc_offset)). Clearly the paths
in Vector1(int, int) end in athrow, and the verifier fails.

Can anyone explain the reason why the class still cannot pass the
verification, and which verifier needs to be fixed.

****************

public class Vector1 extends java.util.AbstractList
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Utf8               Vector1
   #2 = Class              #1             // Vector1
   #3 = Utf8               java/util/AbstractList
   #4 = Class              #3             // java/util/AbstractList
   #5 = Utf8               <init>
   #6 = Utf8               (II)V
   #7 = Utf8               ()V
   #8 = NameAndType        #5:#7          // "<init>":()V
   #9 = Methodref          #4.#8          // java/util/AbstractList."<init>":()V
  #10 = Utf8               java/lang/Exception
  #11 = Class              #10            // java/lang/Exception
  #12 = Methodref          #11.#8         // java/lang/Exception."<init>":()V
  #13 = Utf8               main
  #14 = Utf8               ([Ljava/lang/String;)V
  #15 = NameAndType        #5:#6          // "<init>":(II)V
  #16 = Methodref          #2.#15         // Vector1."<init>":(II)V
  #17 = Utf8               Code
  #18 = Utf8               StackMapTable
{
  public Vector1(int, int);
    descriptor: (II)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: iload_1
         1: iflt          11
         4: aload_0
         5: invokespecial #9                  // Method
java/util/AbstractList."<init>":()V
         8: goto          11
        11: new           #11                 // class java/lang/Exception
        14: dup
        15: invokespecial #12                 // Method
java/lang/Exception."<init>":()V
        18: athrow
      StackMapTable: number_of_entries = 1
        frame_type = 255 /* full_frame */
          offset_delta = 11
          locals = [ top, int, int ]
          stack = []

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=1, args_size=1
         0: new           #2                  // class Vector1
         3: bipush        10
         5: iconst_0
         6: invokespecial #16                 // Method "<init>":(II)V
         9: return
}

HotSpot reports the next verifyerror, while J9 does not:
Exception in thread "main" java.lang.VerifyError: Inconsistent
stackmap frames at branch target 11
Exception Details:
  Location:
    Vector1.<init>(II)V @11: new
  Reason:
    Current frame's flags are not assignable to stack map frame's.
  Current Frame:
    bci: @1
    flags: { flagThisUninit }
    locals: { uninitializedThis, integer, integer }
    stack: { integer }
  Stackmap Frame:
    bci: @11
    flags: { }
    locals: { top, integer, integer }
    stack: { }
  Bytecode:
    0000000: 1b9b 000a 2ab7 0009 a700 03bb 000b 59b7
    0000010: 000c bf
  Stackmap Table:
    full_frame(@11,{Top,Integer,Integer},{})


More information about the hotspot-dev mailing list