RFR: JDK-8237528: Inefficient compilation of Pattern Matching for instanceof

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jan 23 18:20:38 UTC 2020


Looks good to me

Maurizio

On 23/01/2020 17:10, Jan Lahoda wrote:
> Hi,
>
> When javac compiles:
> o instanceof String s
>
> it desugars this to:
>
> (let /*synthetic*/ final Object s$temp = o in s$temp instanceof String 
> && (s = (String)s$temp) == (String)s$temp)
>
> The "(s = (String)s$temp) == (String)s$temp)" is there to set the 
> variable "s" to the correct, and still return/have a boolean value. 
> But this produces several unnecessary instructions for the comparison 
> - second cast and unnecessary test/jump. This can be changed to:
>
> (let /*synthetic*/ final Object s$temp = o in s$temp instanceof String 
> && (let s = (String)s$temp; in true))
>
> I.e. the (s = (String)s$temp) == (String)s$temp) is replaced with
>
> (let s = (String)s$temp; in true)
>
> This is a let expression that will execute the assignment as a 
> statement and then return true without any tests. This eliminates the 
> unnecessary cast and test/jump, producing a smaller code (see bytecode 
> before and after below).
>
> Proposed patch:
> http://cr.openjdk.java.net/~jlahoda/8237528/webrev.00/index.html
>
> JBS:
> https://bugs.openjdk.java.net/browse/JDK-8237528
>
> How does this look?
>
> Jan
>
> The bytecode for:
>         if (o instanceof String s) {
>             nop(s);
>         }
>
> current state:
>          0: aload_0
>          1: astore_2
>          2: aload_2
>          3: instanceof    #7                  // class java/lang/String
>          6: ifeq          26
>          9: aload_2
>         10: checkcast     #7                  // class java/lang/String
>         13: dup
>         14: astore_1
>         15: aload_2
>         16: checkcast     #7                  // class java/lang/String
>         19: if_acmpne     26
>         22: aload_1
>         23: invokestatic  #9                  // Method 
> nop:(Ljava/lang/String;)V
>         26: return
>
>
> after the proposed patch:
>          0: aload_0
>          1: astore_2
>          2: aload_2
>          3: instanceof    #7                  // class java/lang/String
>          6: ifeq          18
>          9: aload_2
>         10: checkcast     #7                  // class java/lang/String
>         13: astore_1
>         14: aload_1
>         15: invokestatic  #9                  // Method 
> nop:(Ljava/lang/String;)V
>         18: return
>
> I.e. the instructions at original bytecode indexes 13, 15, 16 and 19 
> disappear.


More information about the compiler-dev mailing list