On Tue, 25 May 2021 14:22:57 GMT, Jan Lahoda <jlah...@openjdk.org> wrote:

> 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 problem with this design is that calling example("foo") forces the VM will 
do 6 checkcast String on "foo", and it doesn't work with sub-patterns. 
Desugaring the guards as static method like with lambdas seems more promising, 
indy can be called with the pairs [String, MethodHandle(s -> s.length() == 0)], 
[String, MethodHandle(s -> s.length() == 0)] and [_,_]  (with the guards passed 
as a constant method handles again like lambdas are desugared).
It means that the indy needs to capture all local variables that are used in 
the guards, instead of passing an int.

I believe that a translation using constant method handles for guards is far 
more efficient than using an int and a backward branch but it has a higher cost 
in term of runtime data structures.

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

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

Reply via email to