Quantcast

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

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Yuting Chen-2
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},{})
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Yuting Chen-2
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},{})
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Remi Forax
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" <[hidden email]>
> À: [hidden email]
> 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},{})
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Michael Rasmussen
Your problem is, that the stackmap frame in your else has top as local
0, instead of an uninitializedThis, meaning else-block doesn't have
flagThisUninit  in the flags, so it shouldn't verify.

This was changed in 8u121, to conform with the Maintenance Releases of
JSRs 336/337 done in 2015.
Prior to that, flags was not compared when checking if stackmap frames
were compatible, apparently J9 hasn't updated to follow this yet.

Also see: http://mail.openjdk.java.net/pipermail/hotspot-dev/2017-January/025781.html

/Michael

On 14 April 2017 at 01:39, Remi Forax <[hidden email]> wrote:

> 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" <[hidden email]>
>> À: [hidden email]
>> 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},{})
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Yuting Chen-2
Thanks, Remi and Michael.

The difference appears only when all of the paths end in athrow. Then
what does the comment ("Return TRUE if all code paths starting with
start_bc_offset end in bytecode athrow or loop") in verifier.cpp mean?
It seems that J9 follows this comment.

Both verifiers can decline the class if "athrow" is changed to "return".

On Thu, Apr 13, 2017 at 3:54 PM, Michael Rasmussen
<[hidden email]> wrote:

> Your problem is, that the stackmap frame in your else has top as local
> 0, instead of an uninitializedThis, meaning else-block doesn't have
> flagThisUninit  in the flags, so it shouldn't verify.
>
> This was changed in 8u121, to conform with the Maintenance Releases of
> JSRs 336/337 done in 2015.
> Prior to that, flags was not compared when checking if stackmap frames
> were compatible, apparently J9 hasn't updated to follow this yet.
>
> Also see: http://mail.openjdk.java.net/pipermail/hotspot-dev/2017-January/025781.html
>
> /Michael
>
> On 14 April 2017 at 01:39, Remi Forax <[hidden email]> wrote:
>> 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" <[hidden email]>
>>> À: [hidden email]
>>> 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},{})
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Michael Rasmussen
On 14 April 2017 at 02:15, Yuting Chen <[hidden email]> wrote:
> Thanks, Remi and Michael.
>
> The difference appears only when all of the paths end in athrow. Then
> what does the comment ("Return TRUE if all code paths starting with
> start_bc_offset end in bytecode athrow or loop") in verifier.cpp mean?
> It seems that J9 follows this comment.
>
> Both verifiers can decline the class if "athrow" is changed to "return".

Yes, for constructors, if exit is via return, then there cannot be any
uninitializedThis, but allowed if exit is via athrow.

But, your problem is, that your two frame aren't assignable to each other.

>>> Current Frame:
>>>    bci: @1
>>>    flags: { flagThisUninit }
>>>    locals: { uninitializedThis, integer, integer }
>>>    stack: { integer }
>>>  Stackmap Frame:
>>>    bci: @11
>>>    flags: { }
>>>    locals: { top, integer, integer }
>>>    stack: { }

While the locals are compatible, the flags are not, you cannot go from
{ flagThisUninit } to {}
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/tip/src/share/vm/classfile/stackMapFrame.cpp#l190

/Michael
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Yuting Chen-2
It seems that J9 forgot to check the flags when athrow follows.

On Thu, Apr 13, 2017 at 4:21 PM, Michael Rasmussen
<[hidden email]> wrote:

> On 14 April 2017 at 02:15, Yuting Chen <[hidden email]> wrote:
>> Thanks, Remi and Michael.
>>
>> The difference appears only when all of the paths end in athrow. Then
>> what does the comment ("Return TRUE if all code paths starting with
>> start_bc_offset end in bytecode athrow or loop") in verifier.cpp mean?
>> It seems that J9 follows this comment.
>>
>> Both verifiers can decline the class if "athrow" is changed to "return".
>
> Yes, for constructors, if exit is via return, then there cannot be any
> uninitializedThis, but allowed if exit is via athrow.
>
> But, your problem is, that your two frame aren't assignable to each other.
>>>> Current Frame:
>>>>    bci: @1
>>>>    flags: { flagThisUninit }
>>>>    locals: { uninitializedThis, integer, integer }
>>>>    stack: { integer }
>>>>  Stackmap Frame:
>>>>    bci: @11
>>>>    flags: { }
>>>>    locals: { top, integer, integer }
>>>>    stack: { }
>
> While the locals are compatible, the flags are not, you cannot go from
> { flagThisUninit } to {}
> http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/tip/src/share/vm/classfile/stackMapFrame.cpp#l190
>
> /Michael
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Tim Ellison-2
I will bring this to the attention of the J9 verifier team and ask them to
comment on the behavior.

Regards,
Tim

On 14 Apr 2017 00:39, "Yuting Chen" <[hidden email]> wrote:

> It seems that J9 forgot to check the flags when athrow follows.
>
> On Thu, Apr 13, 2017 at 4:21 PM, Michael Rasmussen
> <[hidden email]> wrote:
> > On 14 April 2017 at 02:15, Yuting Chen <[hidden email]> wrote:
> >> Thanks, Remi and Michael.
> >>
> >> The difference appears only when all of the paths end in athrow. Then
> >> what does the comment ("Return TRUE if all code paths starting with
> >> start_bc_offset end in bytecode athrow or loop") in verifier.cpp mean?
> >> It seems that J9 follows this comment.
> >>
> >> Both verifiers can decline the class if "athrow" is changed to "return".
> >
> > Yes, for constructors, if exit is via return, then there cannot be any
> > uninitializedThis, but allowed if exit is via athrow.
> >
> > But, your problem is, that your two frame aren't assignable to each
> other.
> >>>> Current Frame:
> >>>>    bci: @1
> >>>>    flags: { flagThisUninit }
> >>>>    locals: { uninitializedThis, integer, integer }
> >>>>    stack: { integer }
> >>>>  Stackmap Frame:
> >>>>    bci: @11
> >>>>    flags: { }
> >>>>    locals: { top, integer, integer }
> >>>>    stack: { }
> >
> > While the locals are compatible, the flags are not, you cannot go from
> > { flagThisUninit } to {}
> > http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/tip/
> src/share/vm/classfile/stackMapFrame.cpp#l190
> >
> > /Michael
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Yuting Chen-2
The bug has been fixed.  They suggested me to change a new version.
After all, it's interesting.

On Mon, Apr 17, 2017 at 12:57 PM, Tim Ellison <[hidden email]> wrote:

> I will bring this to the attention of the J9 verifier team and ask them to
> comment on the behavior.
>
> Regards,
> Tim
>
> On 14 Apr 2017 00:39, "Yuting Chen" <[hidden email]> wrote:
>>
>> It seems that J9 forgot to check the flags when athrow follows.
>>
>> On Thu, Apr 13, 2017 at 4:21 PM, Michael Rasmussen
>> <[hidden email]> wrote:
>> > On 14 April 2017 at 02:15, Yuting Chen <[hidden email]> wrote:
>> >> Thanks, Remi and Michael.
>> >>
>> >> The difference appears only when all of the paths end in athrow. Then
>> >> what does the comment ("Return TRUE if all code paths starting with
>> >> start_bc_offset end in bytecode athrow or loop") in verifier.cpp mean?
>> >> It seems that J9 follows this comment.
>> >>
>> >> Both verifiers can decline the class if "athrow" is changed to
>> >> "return".
>> >
>> > Yes, for constructors, if exit is via return, then there cannot be any
>> > uninitializedThis, but allowed if exit is via athrow.
>> >
>> > But, your problem is, that your two frame aren't assignable to each
>> > other.
>> >>>> Current Frame:
>> >>>>    bci: @1
>> >>>>    flags: { flagThisUninit }
>> >>>>    locals: { uninitializedThis, integer, integer }
>> >>>>    stack: { integer }
>> >>>>  Stackmap Frame:
>> >>>>    bci: @11
>> >>>>    flags: { }
>> >>>>    locals: { top, integer, integer }
>> >>>>    stack: { }
>> >
>> > While the locals are compatible, the flags are not, you cannot go from
>> > { flagThisUninit } to {}
>> >
>> > http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/tip/src/share/vm/classfile/stackMapFrame.cpp#l190
>> >
>> > /Michael
Loading...