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

Jan Lahoda jan.lahoda at oracle.com
Thu Jan 23 17:10:36 UTC 2020


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