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