As part of JDK-8205637 we want to provide invokedynamic based implementations for the following var-args methods:
java.io.PrintStream::printf(String, Object...)
java.io.PrintStream::printf(Locale, String, Object...)
java.io.PrintStream::format(String, Object...)
java.io.PrintStream::format(Locale, String, Object...)
java.io.PrintWriter::printf(String, Object...)
java.io.PrintWriter::printf(Locale, String, Object...)
java.io.PrintWriter::format(String, Object...)
java.io.PrintWriter::format(Locale, String, Object...)
java.lang.String::format(Object..)
java.lang.String::format(Locale, Object...)
java.lang.String::format(String, Object..)
java.lang.String::format(Locale, String, Object...)
java.util.Formatter::format(String, Object...)
java.util.Formatter::format(Locale, String, Object...)
The intention is to base the invokedynamic implementation on java.util.Formatter, but use simpler, optimized
code where the format string and argument type allows it.
We have a fully working prototype for this feature. There are two implementations, one more directly replicating and leveraging the existing Formatter code, the other based on [java.lang.invoke.StringConcatFactory](https://docs.oracle.com/javase/10/docs/api/java/lang/invoke/StringConcatFactory.html). It is possible to implement all above methods on top of both implementation, although the former implementation is easier to fit to the methods with a pre-existing Appendable (as in all methods above except the String methods), whil the latter is a better fit for the String methods and requires jumping through some hoops for the other methods in the list.
On the other hand, the StringConcatFactory based implementation allows some further optimization since it pre-renders all parts and is therefore able to calculate the exact length of the formatted string.
However, there is one case where the StringConcatFactory based method exposes slightly different behaviour from normal Formatter code, and that is when an exception occurs during the formatting. With java.util.Formatter, the parts that have been rendered up until the exception occurred are appended to the formatter's Appendable. With the StringConcatFactory, an exception in any part of the formatting will result in no output at all. Note that this is only true for the non-String methods, since output from a String method throwing an exception will not be visible to the caller.
Because of the issues explained above, a viable approach might be to use the StringConcatFactory based implementation only for String methods, and use the Appendable based implementation for the rest of the supported methods.
We want to make a few changes to java.util.Formatter to make it more easy to support its use from indy bootstrap. Specifically, we need a method to compile a format string into a list of static strings and formatter tokens. However, since providing this functionality to users of the JDK is not a goal of JDK-8205637, there is no use in exposing that new functionality as part of the public java.util.Formatter API. Instead, we plan to implement the new features using non-public APIs.
For testing, we need to make sure all tests are run in all possible implementations. This can be done by the following steps:
- running tests with the compiler and runtime options (for the current prototype this is JTREG="OPTIONS=-javacoption:-XDdoIntrinsics")
- adding helper code to explicitly exercise test code in all configurations
- adding specific tests for Formatter intrinsic bootstrap code