[lworld] VerifyError: Bad type on operand stack, limitation in javac for value type constructors
Srikanth
srikanth.adayapalam at oracle.com
Mon Jul 16 13:17:17 UTC 2018
I am not Paul :) but the present behavior you describe looks correct to me.
Bottomline, javac is generating bad code for the case concerned.
https://bugs.openjdk.java.net/browse/JDK-8207332
I doubt that there is a verifier defect here, but we will see after
javac reforms itself.
Thanks
Srikanth
On Saturday 14 July 2018 12:17 AM, Harold David Seigel wrote:
> Hi Paul,
>
> For a withfield instruction, do you expect the verifier to push the
> type of the field on its stack or the type of the valuetype containing
> the field. Currently, it pushes the valuetype on the stack.
>
> This is a JVM Spec issue.
>
> Harold
>
>
> On 7/13/2018 2:24 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