[lworld] VerifyError: Bad type on operand stack, limitation in javac for value type constructors

Srikanth srikanth.adayapalam at oracle.com
Mon Jul 16 13:15:31 UTC 2018


Thanks Paul,

This is a tricky issue indeed, but not a hard limitation.
I have raised: https://bugs.openjdk.java.net/browse/JDK-8207332 for this 
problem.

I will tackle the related but simpler problem against
https://bugs.openjdk.java.net/browse/JDK-8207341

first and then get to JDK-8207332.

Thanks!
Srikanth

On Friday 13 July 2018 11:54 PM, Paul Sandoz wrote:
> Hi,
>
> The program below compiles but fails when executed:
>
>   $ java -XX:+EnableValhalla A
> Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
> Exception Details:
>    Location:
>      A$Point.$makeValue$()LA$Point; @12: i2b
>    Reason:
>      Type 'A$Point' (current frame, stack[1]) is not assignable to integer
>    Current Frame:
>      bci: @12
>      flags: { }
>      locals: { 'A$Point' }
>      stack: { 'A$Point', 'A$Point' }
>    Bytecode:
>      0000000: cb00 024b 2a2a 03cc 0004 594b 91cc 0003
>      0000010: 4b2a b0
>
> 	at A.main(A.java:31)
>
>
> The cause is this constructor:
>
>      Point() {
>          x = y = 0; // This is the cause
>      }
>
> the byte code of which is:
>
>    A$Point();
>      descriptor: ()V
>      flags: (0x0000)
>      Code:
>        stack=1, locals=1, args_size=1
>           0: aload_0
>           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
>           4: return
>        LineNumberTable:
>          line 6: 0
>
>
> If the constructor is updated to the following then things work:
>
>      Point() {
>          x = 0;
>          y = 0;
>      }
>
>    static A$Point point();
>      descriptor: ()LA$Point;
>      flags: (0x0008) ACC_STATIC
>      Code:
>        stack=2, locals=0, args_size=0
>           0: iconst_0
>           1: iconst_0
>           2: invokestatic  #6                  // Method point:(II)LA$Point;
>           5: areturn
>
>
> There is a limitation in javac's current approach mapping field assignments to arguments passed to the static factory method.
>
> Paul.
>
> public class A {
> static final __ByValue class Point {
>      final int x;
>      final int y;
>
>      Point() {
>          x = y = 0; // This is the cause
>      }
>
>      static Point point(int x, int y) {
>          Point p = __MakeDefault Point();
>          p = __WithField(p.x, x);
>          p = __WithField(p.y, y);
>          return p;
>      }
>
>      @Override
>      public boolean equals(Object o) {
>          if (!(o instanceof Point)) return false;
>          Point op = (Point) o;
>
>          return x == op.x && y == op.y;
>      }
>
>      static Point point() {
>          return point(0, 0);
>      }
> }
>
> public static void main(String[] args) {
>    Point p = Point.point();
> }
> }
>



More information about the valhalla-dev mailing list