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

Remi Forax forax at univ-mlv.fr
Thu Apr 13 22:39:37 UTC 2017


Disclaimer, i'm not an hotspot guy. 

J9 seems wrong, to me.

If you just take a look to the code,
you have a path to go out of the constructor without having 'this' fully initialized,
so whatever the VM impelemntations say, this code is not a valid one.

Now, Hotspot refuses to merge a path where this is initialized with a path where this is not initialized because it will forget that there is a path where this is not initialized,
it seems to be the right thing to do.

cheers,
Rémi

----- Mail original -----
> De: "Yuting Chen" <chenyt.cs.sjtu at gmail.com>
> À: hotspot-dev at openjdk.java.net
> Envoyé: Vendredi 14 Avril 2017 00:02:42
> Objet: Fwd: HotSpot and IBM's J9 behave a little different when verifying this class

> Re-post my previous example.
> 
> 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