RFR (XS) 8055146: Split Verifier incorrectly throws VerifyError for getstatic of an array field

harold seigel harold.seigel at oracle.com
Mon Jan 5 20:24:55 UTC 2015


Hi David,

Thanks for looking at this change.

For getfield, JVM 8 Spec says:

    A /getfield/ instruction with operand |CP| is type safe iff |CP|
    refers to a constant pool entry denoting a field whose declared type
    is |FieldType|, declared in a class |FieldClass|, and one can
    validly replace a type matching |FieldClass| with type |FieldType|
    on the incoming operand stack yielding the outgoing type state.
    |FieldClass| must not be an array type. |protected| fields are
    subject to additional checks (§4.10.1.8
    <http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.8>).


The description of getstatic in JVMS-8 
<http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.9.getstatic> 
is similar, but does not restrict FieldClass from being an array.

In the ArrayField example, the FieldClass is ArrayField.  This is not an 
array type and so is a valid FieldClass for a getfield instruction.

       public void test();
         descriptor: ()V
         flags: ACC_PUBLIC
         Code:
           stack=2, locals=3, args_size=1
              0: getstatic     #2                  // Field
    sarray:[Ljava/lang/Object;
              3: astore_1
              4: aload_0
              5: getfield      #3                  // Field
    array:[Ljava/lang/Object;
                     ...

    Constant pool:
        #1 = Methodref          #7.#19         //
    java/lang/Object."<init>":()V
        #2 = Fieldref           #6.#20         //
    ArrayField.sarray:[Ljava/lang/Object;
        #3 = Fieldref           #6.#21         //
    ArrayField.array:[Ljava/lang/Object;
        #4 = Class              #22            // java/lang/RuntimeException
        #5 = Methodref          #4.#19         //
    java/lang/RuntimeException."<init>":()V
    *#6 = Class              #23 // ArrayField*
                             ...


In the below example, the FieldClass is an array.  According to JVMS-8, 
this is valid for getstatic (and putstatic) but not valid for getfield 
(and putfield):

       public static void main(java.lang.String[]);
         descriptor: ([Ljava/lang/String;)V
         flags: ACC_PUBLIC, ACC_STATIC
         Code:
           stack=2, locals=2, args_size=1
              0: getstatic     #2                  // Field
    "[C".out:Ljava/io/PrintStream;
              3: putstatic     #2                  // Field
    "[C".out:Ljava/io/PrintStream;
                       ...

    Constant pool:
        #1 = String             #30            // Hello
        #2 = Fieldref           #13.#24        //
    "[C".out:Ljava/io/PrintStream;
        #3 = Methodref          #25.#28        //
    java/io/PrintStream.println:(Ljava/lang/String;)V
        #4 = Methodref          #17.#10        //
    java/lang/Object."<init>":()V
        #5 = Methodref          #23.#16        //
    java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        #6 = Utf8               ()V
        #7 = Utf8               Getstatic_Test
        #8 = Utf8               java/lang/Integer
        #9 = Utf8               <init>
       #10 = NameAndType        #9:#6          // "<init>":()V
       #11 = Utf8               out
       #12 = Utf8               java/io/PrintStream
    *  #13 = Class              #22 // "[C"*
                 ...


The bug fix allows the FieldClass type to be an array for getstatic and 
putstatic, bu tthrows VerifyError for getfield and putfield.

Thanks, Harold


On 1/4/2015 9:13 PM, David Holmes wrote:
> Hi Harold,
>
> On 1/01/2015 2:38 AM, harold seigel wrote:
>> Hi,
>>
>> Please review this small fix for bug 8055146.  The fix allows the
>> operands of getstatic and putstatic bytecodes to be arrays, instead of
>> throwing VerifyError exceptions.
>>
>> Open webrev:  http://cr.openjdk.java.net/~hseigel/bug_8055146/
>>
>> JBS bug: https://bugs.openjdk.java.net/browse/JDK-8055146
>
> I'm missing something here. It says for getField that it must not be 
> an array type; but doesn't say that for getStatic. This puzzles me on 
> two fronts:
>
> 1. Why should there be any difference between accessing a static 
> versus a non-static field in this regard?
>
> 2. If I code this:
>
> public class ArrayField {
>   static Object[] sarray;
>   Object[] array;
>
>   public void test() {
>     Object o = sarray;
>     Object o2 = array;
>     if (o == o2) throw new RuntimeException();
>   }
> }
>
> the bytecode generated is:
>
>   public void test();
>     Code:
>        0: getstatic     #2                  // Field 
> sarray:[Ljava/lang/Object;
>        3: astore_1
>        4: aload_0
>        5: getfield      #3                  // Field 
> array:[Ljava/lang/Object;
>        ...
>
> so this seems to be using getField for an array field when it is not 
> allowed ??
>
> Thanks,
> David
>
>> The fix was tested with JCK lang and VM tests, hotspot JTReg, and NSK
>> split_verifier tests.
>>
>> Thanks, Harold



More information about the hotspot-runtime-dev mailing list