31
Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Embed Size (px)

Citation preview

Page 1: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Nashorn: JavaScript that doesn’t suck

Tomer Gabel, WixBuildStuff, November 2014

Page 2: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Agenda

• History

• Features

• Behind the scenes

• Performance

• Juggling Act

Page 3: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

History

• Existing Rhino engine:– Slow– Non-compliant– Did I mention slow?

• JavaScript since 1998:– Adoption went through

the roof– Technology advances

(V8, SpiderMonkey…)

Page 4: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Nashorn in a nutshell

• Project Nashorn– Started in July 2011

– Integrates with JSR-223

– Reference use-case

for JSR-292

• Released with Java 8 in

March 2014

Page 5: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Why bother?

Why you care• Extensibility and scripting

– Macro systems (a la VBA)– Event hooks

• Server-side JavaScript – More on this later

• End-user programmability– Rule engines– Reporting engines/ETL– BPL and workflow

• … and more

Why Oracle cares• Atwood’s law• Node.js

– A real threat to Java’s server-side growth

• Reference use-case for JSR-292– Drive innovation– Drive optimization– Reference implementation

Page 6: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Features

• Self-contained• Small: 1.5MB JAR• Implements ECMAScript 5.1–100% compliant!

• Runtime-compiled to bytecode(no interpreted mode as with Rhino)

• Fast!

Page 7: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

JSR-223 at a glanceimport javax.script.*;

ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine nashorn = manager.getEngineByName("nashorn");

nashorn.eval( "print(\"hello world!\");");

Page 8: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Integrating JSR-223

• Injecting state

nashorn.put("name", "Schnitzel McFry"); nashorn.eval( "print(\"hello \" + name + \"!\");");

Page 9: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Integrating JSR-223

• Invoking JavaScript from Java

nashorn.eval( "function hello(name) { " + " print(\"hello \" + name + \"!\");" + "} " );

Invocable context = (Invocable) nashorn; context.invokeFunction("hello", "world");

Page 10: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Nashorn Extensions

• Java object– Java.type– Java.extend– Java.from– Java.to– Java.super

• A bunch more

Page 11: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Integrating JSR-223

• Invoking Java from JavaScript

nashorn.eval( "var HashMap = Java.type(\"java.util.HashMap\");" + "var map = new HashMap(); " + "map.put(\"name\", \"Schnitzel\"); " + "map.put(\"surname\", \"McFry\"); " );

HashMap<String, String> map = (HashMap<String, String>) nashorn.get("map");

Page 12: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Integrating JSR-223

• Implementing a Java interface

nashorn.eval( "var runnable = { " + " \"run\": function() { print(\"hello world\"); }" + "} " );

Invocable invocable = (Invocable) nashorn;Runnable runnable = invocable.getInterface( nashorn.get("runnable"), Runnable.class);

Page 13: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Integrating JSR-223

• Single Abstract Method (SAM) promotion:

nashorn.eval( "var Thread = Java.type(\"java.lang.Thread\");" + "var thread = new Thread(function() { " + " print(\"hello world\"); " + "} ); " );

Thread thread = (Thread) nashorn.get("thread");thread.start();thread.join();

Page 14: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

BEHIND THE SCENES

Page 15: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• JavaScript is dynamic– Things can change at runtime– Optimization is all about assumptions

Page 16: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• JavaScript is dynamic– Things can change at runtime– Optimization is all about assumptions

• For example, what is the type of:var x = 500000;

Page 17: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• JavaScript is dynamic– Things can change at runtime– Optimization is all about assumptions

• For example, what is the type of:var x = 500000;x *= 500000; And now?

Page 18: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• JavaScript is dynamic– Things can change at runtime– Optimization is all about assumptions

• For example, what is the type of:var x = 500000;x *= 500000; And now?

• How would you implement this?

Page 19: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• Naïve multiplication operator:– Receive LHS and RHS as java.lang.Objects– Unbox– Test for potential over/underflow– Multiply via appropriate codepath– Box and return

• You can specialize via static analysis• … but on-the-fly optimization is better

Page 20: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• That’s just one example.– Primitive widening– Dynamic dispatch– Type coercions – Prototype mutation

• All of these per call site!

function square(x) { return x * x;}

square(10) //== 100square(3.14) //== 9.8596square("wat") //== NaN

Page 21: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

The challenge

• Runtime code manipulation is not the JVM’s strong suite–Can only load entire classes

–High overhead

–Hard PermGen space limit

–Class unloading issues

Page 22: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Enter JSR 292

• Based on an experimental project, the

Da Vinci Machine

• Adds two new concepts to the JVM:– invokedynamic bytecode instruction

– MethodHandles

• The first bytecode extension since 1999!

Page 23: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

invokedynamic

• The name is misleading

• It’s not about invocation

• … but about runtime linkage

Page 24: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

java.lang.invoke

• MethodHandle– An immutable

function pointer– Composable:• Guards• Exception handlers• Argument mutation

– Typesafe andJIT-optimizable

• CallSite– Binds an

invokedynamic “instance” to a target MethodHandle

– Optionally mutable

Page 25: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Why is this cool?

• Generated code is linked at runtime

• Code is hotswappable– Guards for branching (over/underflow)

– SwitchPoints for hotswap (promotions)

• Hotswapping is lightweight– No class generation or loading

• Resulting codepath can be JITted

Page 26: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Don’t forget JEP 122

• The PermGen space is no more– Now called “Metaspace”

– Resides in native heap

– Block allocator and classloader isolation

– Dynamic size (with bounds)• Maximum size (hard)

• Low/high watermark for GC

• This applies to all GCs (not just G1)

Page 27: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

SO HOW DOES IT PERFORM?

Page 28: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Pretty damn fast!

• 2-10 times faster than Rhino• ~60% percent of V8• Not much research out there

Page 29: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

Avatar.js

• Implements the Node model and API on the JVM

• Supports most modules– Some natively– Some via JNI

• … and it does work!

• mocha• coffee-script• uglify-js• underscore• request• async• jade• express• mongodb• Redis

Most popular per nodejsmodules.org

Supported module highlights

Page 30: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

QUESTIONS?

Page 31: Nashorn: JavaScript that doesn’t suck Tomer Gabel, Wix BuildStuff, November 2014

WE’RE HIRING!

Contact me:• http://www.tomergabel.com• [email protected]• @tomerg