RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v4]

Jan Lahoda jlahoda at openjdk.java.net
Tue May 25 14:25:03 UTC 2021


On Tue, 25 May 2021 14:13:55 GMT, Rémi Forax <forax at openjdk.org> wrote:

> > Thanks Evgeny, I'll take a look.
> > @forax, do you mean why there is "0" in:
> > 11: invokedynamic #13, 0
> > ?
> 
> Not this one, the one on the stack.
> 
> 7: iconst_0 <---- this zero
> 8: istore_3
> 9: aload_2
> 10: iload_3
> 11: invokedynamic #13, 0 // InvokeDynamic
> #0:typeSwitch:(Ljava/lang/Object;I)I
> 
> Why the descriptor is (Ljava/lang/Object;I)I instead of (Ljava/lang/Object;)I,
> what is the semantics associated to that integer ?

The reason for this integer (which is not a constant in the case of this switch) is to restart the matching in case guards fail to "match". Considering the example here:

class Example {
        void example(Object o) {
                switch (o) {
                case String s && s.length() == 0 ->
                        System.out.println("1st case");
                case String s && s.length() == 1 ->          // line 6
                        System.out.println("2nd case");      // line 7
                case String s ->                             // line 8
                        System.out.println("3rd case");      // line 9
                default ->                                   // line 10
                        System.out.println("default case");  // line 11
                }
        }
}


If `o` is `String`, then the first call to indy will be `indy[...](o, 0)`, returning `0`. Then the guard will be evaluated `s.length() == 0`. If the length is not zero, the local variable 3 will be reassigned to `1`(bytecode index 58, 59) and the whole switch is restarted - just this time, the matching in the indy will start at index `1`, not `0`, i.e. `indy[...](o, 1)`. And so on. I believe there is a text explaining the meaning of the parameter in the javadoc of the bootstrap, and in TransPatterns in javac.

> 
> > The "0" is an artifact of how invokedynamic is represented in the classfile (invokedynamic, 2 bytes of constant pool reference, byte 0, byte 0) - javap shows the value of the first zero byte. That is probably not needed anymore, but there is nothing special in this patch, I think - all invokedynamic calls look like this, AFAIK.
> 
> I know that a little to well, i'm one of the guys behind the design of indy :)

-------------

PR: https://git.openjdk.java.net/jdk/pull/3863



More information about the build-dev mailing list