JDK-8025435 : Specialized library functions for optimistic typing
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
Optimistic typing will increase the need to call library methods with primitive parameters and return values.
We need to investigate the requirements and add specialized methods as necessary.
I have done some very promising strides in specializing push and pop as part of the optimistic frame work. Taking over this.
I experimented with specialized library functions for optimistic typing for a few days. Here's a summary of what I found.
Nashorn optimistic currently supports applying optimistic assumptions to non-optimistic library functions by adding a return value filter to the method handle. E.g. a method that returns double may work in an optimistic context expecting an int using a return value filter that checks if the return value represents an int and throw an UnwarrantedOptimismException if it does not. This is pretty simple and straightforward.
I spent considerable time getting "proper" optimistic library functions running in optimistic mode. I ran into several problems which I'll explain below, coming to the conclusion that the current approach - adapting MethodHandles that are specialized but not themselves optimistic for use in an optimistic context - is to be preferred as it is much simpler yet not significantly slower.
The first problem I ran to is that we now need to handle two different sets of specialized MethodHandles all the way down to the CompiledFunctions class. Optimistic library MethodHandles must be dealt with separately from both non-optimistic specialized library MethodHandles and recompilable function handles because they require a programPoint parameter to be bound to them to identify the callsite. This was so hairy to get right that I ended up cheating for the purpose of my experiments, adding special purpose code for the functions I was working with.
The next problem I found was that we still seem to need a matching non-optimistic specialized MethodHandle for each optimistic one. Consider an optimistic parseInt implementation that throws UnwarrentedOptimismException if the result can't be represented as int. If we call this with parseInt("xxx", 10) it will produce NaN, raising an UnwarrentedOptimismException. This will trigger recompilation of the calling method. However, the new deoptimized code will still be optimistic (just assuming double instead of int) and the callsite for above parseInt invocation will still link to the same optimistic MethodHandle, causing another round of recompilation - unless we add some special smarts or there is a better matching non-optimistic specialized version available.
Finally, if we need to have both optimistic and non-optimistic specialized functions, this will cause a lot of redundancy on the implementation side. Optimistic and non-optimistic specializations will be very similar except for handling of non-int return values. Of course we could implement one on top of the other, but we'll lose more than what we gain from optimistic implementation in the first place.
On the other hand, the benefits for optimistic library functions I measured were very small. Comparing both approaches with parseInt using a microbenchmark I could hardly see any difference. Unless I oversaw something I think explicitly optimistic library functions are not worth it.