In the class com.sun.tools.javac.comp.Lower, the methods visitStringSwitch and visitEnumSwitch produce code which maps a string or enum to a locally determined index set.
The logic for this is complex, voluminous, and difficult to optimize. In particular, the map array used for enum switches is not constant (we don't have frozen arrays yet), and the decision logic used to index strings likewise uses non-constant values (the String.hashCode).
Shaping the decision logic for both strings and enums is a job for the JVM runtime, not for the static compiler. An invokedynamic statement should be "planted" at the head of each such switch to map the expected inputs to the compact index set. As withJDK-8085796, this will allow the runtime to compose code shapes that the JIT is ready to optimize. In particular, if mapping arrays are to be used, they can be marked @Stable, which is a trick the static compiler cannot use (in general).
The static arguments to the indy bootstrap (a switch indexer metafactory) will be an ordered sequence of expected case values, or (in the case of enums) their name strings. At link time, the metafactory can choose the best available decision tactic for the particular strings in question, and the particular optimizations known to the JIT.
Since there was a limit (before Java 11) of about 200 arguments to a BSM, the static compiler may be called upon to construct a local method to invoke the metafactory (or create a jumbo array) using local code. But in most cases, a single indy instruction is all that's needed. (This would also be an application of a CONSTANT_Group CP type, if that existed.)
The logic for this is complex, voluminous, and difficult to optimize. In particular, the map array used for enum switches is not constant (we don't have frozen arrays yet), and the decision logic used to index strings likewise uses non-constant values (the String.hashCode).
Shaping the decision logic for both strings and enums is a job for the JVM runtime, not for the static compiler. An invokedynamic statement should be "planted" at the head of each such switch to map the expected inputs to the compact index set. As with
The static arguments to the indy bootstrap (a switch indexer metafactory) will be an ordered sequence of expected case values, or (in the case of enums) their name strings. At link time, the metafactory can choose the best available decision tactic for the particular strings in question, and the particular optimizations known to the JIT.
Since there was a limit (before Java 11) of about 200 arguments to a BSM, the static compiler may be called upon to construct a local method to invoke the metafactory (or create a jumbo array) using local code. But in most cases, a single indy instruction is all that's needed. (This would also be an application of a CONSTANT_Group CP type, if that existed.)
- relates to
-
JDK-6827009 Project Coin: Strings in Switch
- Closed
-
JDK-8198477 Arrays.binarySearch on constant array should be optimized by the JIT
- Open
-
JDK-8286190 Add test to verify constant folding for Enum fields
- Resolved
-
JDK-8161245 Enums should be fully optimized
- Closed