Hi folks,

JDK 8u40 was released today, and I wanted to take a moment to summarize some of 
the new stuff in Nashorn since 8u25.

First of all, I want to get the bad news out of the way. There is, 
unfortunately, a functional regression. It was discovered too late in the 
development cycle for the fix to make the deadline for 8u40, so we could really 
do nothing except grit our teeth and accept it'll have to go out like this. 
Namely, passing of JavaScript arrays to Java methods in the vararg position is 
broken, for details see <https://bugs.openjdk.java.net/browse/JDK-8072596>. We 
used to convert the JS array to a Java array of the required type in vararg 
position, but unfortunately we now convert it to ScriptObjectMirror instead and 
that causes a ClassCastException (as a ScriptObjectMirror isn't a Java array, 
obviously). This was not intended and we will revert to the old behavior no 
later than in the next minor release, 8u60. Temporary workaround (should you 
choose to upgrade to 8u40) is to use Java.to() explicitly in such situations. I 
know it's not ideal and it will certainly break someone's existing code; I'm 
truly sorry about that. Most we can do at the moment is to make you aware of 
the issue. (The 9 and 8u-dev repositories have a fix, so neither the 9 EA 
builds nor the shortly coming 8u60 EA builds have the bug.)

Let's move on to brighter things. Here's some new features and improvements in 
8u40:

* Nashorn compiler has fairly powerful static type inference capabilities for 
local variables and expressions now. While JavaScript is notoriously hard to 
analyze statically, we still put in an analyzer that does a fair job of 
inferring static types and then using them to emit optimized bytecode. The 
bytecode emitted for e.g. the "crypto" Octane benchmark is now pretty close to 
the bytecode you'd get if you compiled a Java implementation of those same 
algorithms. In other words, Nashorn's gotten much better at both number 
crunching and asm.js-like workloads. The static type inference is always on.

* Optimistic typing. It actually complements static type inference: what types 
can't be statically inferred will be speculated upon, from more optimistic 
(it's an int!) to a less optimistic (it's a floating point number!) to the 
ultimately not optimistic at all (well, duh, it's an object after all). Nashorn 
has a full gradual code deoptimization framework, complete with on-stack code 
replacement built into it now for this purpose. Optimistic typing typically 
makes the warmup worse, but the warmed-up performance is significantly better, 
hence it's best for use with long-running applications. It's off by default, 
you can use the "--optimistic-types=true" command line switch to turn it on. 
There's a blog post that further elaborates on it: 
<https://blogs.oracle.com/nashorn/entry/nashorn_performance_work_in_the>. 
Marcus and I have worked on this since October 2013 and it's great that we 
finally shipped it to you!

* Function.prototype.bind and Function.prototype.call now work on everything 
Nashorn can call, *including* POJO methods, instances of @FunctionalInterface 
classes etc. The tests included with the feature can give you some examples of 
binding and calling these non-JS callables: 
<http://hg.openjdk.java.net/jdk9/dev/nashorn/file/ad912b034639/test/script/basic/JDK-8051778.js>.
 It takes a bit of getting used to, but since POJO methods don't have the 
Function as their prototype, you can't just invoke "somePojoMethod.bind(...)" 
but must instead use Function.prototype.bind.call(somePojoMethod, this, args). 
Yep, you're .call()-ing Function.prototypebind, but hey, you knew JS is a 
functional language, didn't you? (Horrible protip: you can just type 
Function.bind instead of Function.prototype.bind, since the Function object is 
itself a function (being a JS class constructor), that is "Function instanceof 
Function" holds true). What about Function.prototype.apply, you might ask? 
Well, apply is by its nature a variable-arity invocation. It should work with 
vararg POJO methods, but only with them. You invoke it as 
"Function.apply.call(pojoMethod, ...)". In the future, we might figure out a 
way to use apply with non-vararg POJO methods too, but no promises on that.

* ClassFilter interface enables you to restrict access to specified Java 
classes from scripts run by a Nashorn script engine; see 
<https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html#classfilter_introduction>
 for details.

Of course, these are the larger things. There is an uncounted number of smaller 
bugfixes and performance improvements as well. This is just a quick mail that I 
intended to fire off fast (first and foremost to warn you of the regression); 
if I forgot to mention any of the new features, I'm sure my teammates will 
follow up.

Thanks,
  Attila.

Reply via email to