SlideShare uma empresa Scribd logo
1 de 98
Baixar para ler offline
Towards	
  na*ve	
  performance	
  with	
  
dynamic	
  languages	
  on	
  the	
  JVM	
  
Marcus	
  Lagergren,	
  Oracle	
  
Towards	
  na*ve	
  performance	
  with	
  
dynamic	
  languages	
  on	
  the	
  JVM	
  
Marcus	
  Lagergren,	
  Oracle	
  
How	
  far	
  does	
  invokedynamic	
  take	
  us?	
  
Towards	
  na*ve	
  performance	
  with	
  
dynamic	
  languages	
  on	
  the	
  JVM	
  
Marcus	
  Lagergren,	
  Oracle	
  
How	
  far	
  does	
  invokedynamic	
  take	
  us?	
  
Pre$y	
  far	
  actually!	
  
The	
  Legal	
  Slide	
  

"THE FOLLOWING IS INTENDED TO OUTLINE OUR
GENERAL PRODUCT DIRECTION. IT IS INTENDED FOR
INFORMATION PURPOSES ONLY, AND MAY NOT BE
INCORPORATED INTO ANY CONTRACT. IT IS NOT A
COMMITMENT TO DELIVER ANY MATERIAL, CODE, OR
FUNCTIONALITY, AND SHOULD NOT BE RELIED UPON
IN MAKING PURCHASING DECISION. THE
DEVELOPMENT, RELEASE, AND TIMING OF ANY
FEATURES OR FUNCTIONALITY DESCRIBED FOR
ORACLE'S PRODUCTS REMAINS AT THE SOLE
DISCRETION OF ORACLE."
	
  
Who	
  am	
  I?	
  
@lagergren	
  
	
  
Agenda	
  
•  Nashorn	
  summary	
  
•  The	
  last	
  nine	
  months	
  of	
  Nashorn	
  and	
  
invokedynamic	
  performance	
  work	
  
•  How	
  did	
  we	
  do	
  it? 	
  	
  
•  The	
  future	
  
Nashorn	
  
•  Part	
  of	
  JDK	
  8	
  
– 100%	
  ECMA	
  compliant	
  JavaScript	
  run*me	
  wriPen	
  
in	
  Java	
  
•  ECMA	
  5.1	
  support	
  
– Limited	
  ECMA	
  6	
  support	
  (8u40)	
  
•  invokedynamic	
  based	
  
•  Generates	
  bytecode	
  
– Currently	
  no	
  AST	
  interpreta*on	
  
Nashorn	
  –	
  release	
  schedule	
  
•  Java	
  8	
  	
  
– First	
  version	
  for	
  public	
  consump*on	
  
Nashorn	
  –	
  release	
  schedule	
  
•  Java	
  8	
  	
  
– First	
  version	
  for	
  public	
  consump*on	
  
•  Java	
  8u20	
  
– Security	
  fixes	
  and	
  several	
  JIT	
  /	
  JDK	
  improvements	
  
Nashorn	
  –	
  release	
  schedule	
  
•  Java	
  8	
  	
  
– First	
  version	
  for	
  public	
  consump*on	
  
•  Java	
  8u20	
  
– Security	
  fixes	
  and	
  several	
  JIT	
  /	
  JDK	
  improvements	
  
•  Java	
  8u40	
  
– Performance	
  release	
  
Nashorn	
  –	
  release	
  schedule	
  
•  Java	
  8	
  	
  
– First	
  version	
  for	
  public	
  consump*on	
  
•  Java	
  8u20	
  
– Security	
  fixes	
  and	
  several	
  JIT	
  /	
  JDK	
  improvements	
  
•  Java	
  8u40	
  
– Performance	
  release	
  
•  Java	
  9	
  	
  
Nashorn	
  –	
  release	
  schedule	
  
•  Java	
  8	
  	
  
– First	
  version	
  for	
  public	
  consump*on	
  
•  Java	
  8u20	
  
– Security	
  fixes	
  and	
  several	
  JIT	
  /	
  JDK	
  improvements	
  
•  Java	
  8u40	
  
– Performance	
  release	
  
•  Java	
  9	
  	
  
Evangelist	
  Blurb	
  
“Nashorn	
  is	
  a	
  really	
  fast	
  100%	
  JS	
  compilant	
  
invokedynamic	
  based	
  JavaScript	
  run*me	
  wriPen	
  
in	
  Java.	
  It	
  runs	
  on	
  top	
  of	
  the	
  JVM”	
  
…	
  or	
  maybe?	
  
“Nashorn	
  is	
  a	
  run*me	
  for	
  dynamic	
  languages	
  on	
  
the	
  JVM.	
  Nashorn	
  takes	
  away	
  the	
  pain	
  and	
  
performance	
  loss	
  of	
  bridging	
  the	
  gap	
  between	
  
language	
  and	
  bytecode.	
  Types,	
  objects	
  and	
  code	
  
are	
  automa*cally	
  adapted	
  to	
  be	
  an	
  op*mal	
  fit	
  in	
  
the	
  JVM	
  mould”	
  
JavaScript	
  
JavaScript	
  
“Once	
  you	
  admit	
  that	
  EVERYTHING	
  IS	
  TERRIBLE,	
  
	
  	
  the	
  universe	
  opens	
  infinitely	
  many	
  doors	
  for	
  	
  	
  	
  
	
  	
  you...	
  	
  TO	
  TERRIBLE.”	
  
	
   	
   	
   	
   	
   	
   	
   	
   	
   	
  -­‐	
  Jerry	
  Kuch	
  
Where	
  were	
  we	
  last	
  October?	
  
Octane	
  Benchmark	
  r31	
  
0	
  
0.2	
  
0.4	
  
0.6	
  
0.8	
  
1	
  
1.2	
  
rhino	
  
nashorn	
  jdk8	
  
Where	
  are	
  we	
  today?	
  
Octane	
  Benchmark	
  r31	
  
0	
  
1	
  
2	
  
3	
  
4	
  
5	
  
6	
  
7	
  
rhino	
  
nashorn	
  jdk8	
  
nashorn	
  jdk9	
  
…	
  against	
  v8	
  
Octane	
  Benchmark	
  r31	
  
0	
  
2	
  
4	
  
6	
  
8	
  
10	
  
12	
  
rhino	
  
nashorn	
  jdk8	
  
nashorn	
  jdk9	
  
v8	
  
v8	
  bleeding	
  edge…	
  
Octane	
  Benchmark	
  r31	
  
0	
  
2	
  
4	
  
6	
  
8	
  
10	
  
12	
  
14	
  
rhino	
  
nashorn	
  jdk8	
  
nashorn	
  jdk9	
  
v8	
  
v8	
  latest	
  
Let’s	
  not	
  forget	
  node	
  
avatar.js	
  
•  Project	
  Avatar	
  
– HTTP	
  benchmark	
  
– REST	
  benchmark	
  
•  Comparable	
  to	
  v8	
  /	
  na*ve	
  performance	
  
•  8u40	
  will	
  deliver	
  plenty	
  of	
  improvements	
  
•  Use	
  of	
  exposed	
  mechanisms	
  
– BufferArrayData
	
  
avatar.js	
  
•  Project	
  Avatar	
  
– HTTP	
  benchmark	
  
– REST	
  benchmark	
  
•  Comparable	
  to	
  v8	
  /	
  na*ve	
  performance	
  
•  8u40	
  will	
  deliver	
  plenty	
  of	
  improvements	
  
•  Use	
  of	
  exposed	
  mechanisms	
  
– BufferArrayData
	
  
The	
  last	
  year	
  
“The	
  Secret	
  Sauce”	
  
Op*mis*c	
  Type	
  Run*me	
  Architecture	
  
[hPp://openjdk.java.net/jeps/196]	
  
Just	
  compile	
  to	
  bytecode!	
  
•  “The	
  JVM	
  is	
  technically	
  advanced	
  and	
  has	
  man	
  
decades	
  of	
  JIT	
  op*miza*ons”	
  
•  “The	
  JVM	
  magically	
  JITs	
  arbitrary	
  bytecode	
  to	
  
fast	
  na*ve	
  code”	
  
Just	
  compile	
  to	
  bytecode!	
  
•  “The	
  JVM	
  is	
  technically	
  advanced	
  and	
  has	
  man	
  
decades	
  of	
  JIT	
  op*miza*ons”	
  
•  “The	
  JVM	
  magically	
  JITs	
  arbitrary	
  bytecode	
  to	
  
fast	
  na*ve	
  code”	
  
•  Nope	
  :-­‐(	
  
function gcd(x, y) {
var a = x;
var b = y;
while (a != b) {

 
if (a > b) {

 
 
a = a - b;

 
} else {

 
 
b = b - a;

 
} 

}
return a;
}

gcd(x, y);
GCD	
  
GCD	
  –	
  Naïve	
  &	
  JS	
  Compliant	
  
public static gcd(Object;Object;Object;)Object;

aload 1
astore 4
aload 2
astore 5
goto L2
aload 4
aload 5
invokedynamic GT:ZOO_Z(Object;Object;)Z;
ifeq L4
aload 4
invokestatic JSType.toNumber(Object;)D
aload 5
invokestatic JSType.toNumber(Object;)D
dsub
invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double;
astore 4
goto L2
aload 5
invokestatic JSType.toNumber(Object;)D
aload 4
invokestatic JSType.toNumber(Object;)D
dsub
invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double;
astore 5
aload 4
aload 5
invokedynamic NE:ZOO_Z(Object;Object;)Z
ifne L3
aload 4
areturn
GCD	
  –	
  vs	
  Ideal	
  
public static gcd(Object;Object;Object;)Object;

aload 1
astore 4
aload 2
astore 5
goto L2
aload 4
aload 5
invokedynamic GT:ZOO_Z(Object;Object;)Z;
ifeq L4
aload 4
invokestatic JSType.toNumber(Object;)D
aload 5
invokestatic JSType.toNumber(Object;)D
dsub
invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double;
astore 4
goto L2
aload 5
invokestatic JSType.toNumber(Object;)D
aload 4
invokestatic JSType.toNumber(Object;)D
dsub
invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double;
astore 5
aload 4
aload 5
invokedynamic NE:ZOO_Z(Object;Object;)Z
ifne L3
aload 4
areturn
public static gcd(Object;II)I

iload 1
istore 3
iload 2
istore 4
iload 3
iload 4
if_icmpeq L10
iload 3
iload 4
if_icmple L12
iload 3
iload 4
isub
istore 3
goto L14
iload 4
iload 3
isub
istore 4
goto L9
iload 3
ireturn
Op*mis*c	
  Types	
  
•  Factor	
  150x	
  difference	
  in	
  execu*on	
  speed	
  
between	
  the	
  two	
  
•  “Generate	
  Java-­‐like	
  bytecode”	
  
Op*mis*c	
  Types	
  
•  Generate	
  as	
  op*mis*c	
  a	
  func*on	
  as	
  possible	
  
•  Surround	
  op*mis*c	
  opera*ons	
  with	
  excep*on	
  
handlers	
  
•  When	
  a	
  type	
  is	
  too	
  narrow	
  
– Store	
  frame	
  state	
  (no	
  bytecode	
  stack)	
  
– Take	
  a	
  con*nua*on	
  and	
  finish	
  method	
  
– Tell	
  linker	
  to	
  regenerate	
  more	
  conserva*vely	
  
Op*mis*c	
  Types	
  
long	
   double	
   Object	
  (pessimis*c)	
  int	
  
	
  
Implementa*on	
  
function f() {
return x * y; // x,y in scope
}
public static f(ScriptFunction;Object;)D
aload 0
invokevirtual ScriptFunction.getScope()LScriptObject;
astore 2 // store scope in slot 2
aload 2 // load scope
invokedynamic get:x(Object;)Object;
aload 2 // load scope
invokedynamic get:y(Object;)Object;
swap
invokestatic JSType.toNumber(Object;)D
dup2_x1
pop2
invokestatic JSType.toNumber(Object;)D
dmul
dreturn	
  
public static f(ScriptFunction;Object;)I
aload 0
invokevirtual ScriptFunction.getScope()ScriptObject;
astore 2 // store scope in slot 2
aload 2
invokedynamic get:x(Object;)I
istore 3
iload 3
aload 2
invokedynamic get:y(Object;)I 
invokedynamic imul(II)I 
ireturn

	
  
public static f(ScriptFunction;Object;)I
aload 0
invokevirtual ScriptFunction.getScope()ScriptObject;
astore 2 // store scope in slot 2
aload 2
invokedynamic get:x(Object;)I // program point 1 
istore 3
iload 3
aload 2
invokedynamic get:y(Object;)I // program point 2
invokedynamic imul(II)I // program point 3 
ireturn

	
  
public static f(ScriptFunction;Object;)I
aload 0
invokevirtual ScriptFunction.getScope()ScriptObject;
astore 2
aload 2
invokedynamic get:x(Object;)I // program point 1 
istore 3
iload 3
aload 2
invokedynamic get:y(Object;)I // program point 2
invokedynamic imul(II)I // program point 3 
ireturn

// catch (UnwarrantedOptimismException e)
iconst_4 
anewarray Object // 4 local variables in frame
iload 3 // load variable 3 (tmp = x)
invokedynamic populateArray([Object;I)[Object; 
goto rwe
iconst_3 
anewarray Object // 3 local variables in frame
rwe: aload 0 // load function
aload 1 // load ‘this’
aload 2 // load scope
invokedynamic populateArray([Object;Object;Object;Object;)[Object;
iconst_0
invokestatic getString$array(I)[String;
invokestatic RewriteException.create(UnwarrantedOptimismException;[Object;
[String;)RewriteException;
athrow	
  
GCD	
  –	
  Ideal	
  
public static gcd(Object;II)I

iload 1
istore 3
iload 2
istore 4
iload 3
iload 4
if_icmpeq L10
iload 3
iload 4
if_icmple L12
iload 3
iload 4
isub
istore 3
goto L14
iload 4
iload 3
isub 
istore 4
goto L9
iload 3
ireturn
GCD	
  –	
  vs	
  Nashorn	
  
public static gcd(Object;II)I

iload 1
istore 3
iload 2
istore 4
iload 3
iload 4
if_icmpeq L10
iload 3
iload 4
if_icmple L12
iload 3
iload 4
isub
istore 3
goto L14
iload 4
iload 3
isub 
istore 4
goto L9
iload 3
ireturn



public static gcd(Object;II)I
try {
iload 1
istore 3
iload 2
istore 4
iload 3
iload 4
if_icmpeq L10
iload 3
iload 4
if_icmple L12
iload 3
iload 4
invokedynamic isub(II)I 
//indy because sub may overflow
istore 3
goto L14
iload 4
iload 3
invokedynamic isub(II)I 
//indy because sub may overflow
istore 4
goto L9
iload 3
ireturn
} catch (UnwarrantedOptimismException e) { 
//save state and throw RewriteException to linker
}
Sta*c	
  Compiler	
  Enhancements	
  
•  Liveness	
  
function liveness() {
var x = 0;
for (var i = 0;i < 10; i++) {
x += i;
}
x += "test";
return x;
}
What	
  about	
  local	
  variables?	
  The	
  slot	
  
type	
  is	
  hard	
  coded	
  in	
  the	
  local	
  
variable	
  table!	
  
Sta*c	
  Compiler	
  Enhancements	
  
•  Liveness	
  
function liveness() {
var x = 0;
for (var i = 0;i < 10; i++) {
x += i;
}
x += "test";
return x;
}
	
  public static liveness(LObject;)LObject;
iconst_0
invokestatic Integer.valueOf (I)Integer;
astore 2
dconst_0
dstore 3
goto L2
aload 2
invokestatic JSType.toNumber (LObject;)D
dload 3
dadd
invokestatic Double.valueOf (D)Double;
astore 2
dload 3
dconst_1
dadd
dstore 3
dload 3
ldc 10.0
dcmpg
iflt L3
aload 2
ldc "test"
invokedynamic ADD:OOO_I(LObject;LObject;)Object
astore 2
aload 2
areturn

local x Ljava/lang/Object; L0 L6 2
local i D L0 L6 3
Sta*c	
  Compiler	
  Enhancements	
  
•  Liveness	
  
function liveness() {
var x = 0;
for (var i = 0;i < 10; i++) {
x += i;
}
x += "test";
return x;
}
	
   public static liveness(Object;)Object;
iconst_0
istore 1
iconst_0
istore 3
iload 3
bipush 10
if_icmpge L10
iload 1
iload 3
invokedynamic iadd(II)I
istore 1
iload 3
dup
iconst_1
invokedynamic iadd(II)I
istore 3
pop
goto L9
iload 1
invokestatic Integer.valueOf(I)Integer;
ldc "test"
invokestatic ADD(Object;Object;)Object;
astore 2
aload 2
areturn
// exception handler goes here...

local x L6 L13 1 I
local x L13 L2 2 Object;
local i L8 L2 3 I
Field	
  Representa*on	
  
Field	
  Representa*on	
  
•  jdk.nashorn.internal.runtime.ScriptObject
–  Contains	
  a	
  PropertyMap
•  Shape	
  
–  Contains	
  a	
  number	
  of	
  fields	
  
•  Scope	
  variables	
  
–  Contains	
  a	
  growing	
  array	
  
•  Spills	
  –	
  also	
  scope	
  variables	
  
–  and	
  lots	
  of	
  other	
  things,	
  e.g.	
  ArrayData
	
  	
  
Field	
  Representa*on	
  
public abstract class ScriptObject 

implements PropertyAccess {

protected Object[] spillObjects;

long spillPrimitives;

// most guards are a ref comparison on map 

private PropertyMap map;
}

public JO$4 extends ScriptObject {

private Object o0, o1, o2, o3;

long p1, p2, p3, p4;
}
	
  	
  	
  	
  	
  	
  
	
  
	
  
Property	
  Maps	
  
PropertyMap

AccessorProperty: red (flags = 0) slot = 0

AccessorProperty: green (flags = 0) slot = 1
AccessorProperty: blue (flags = 0) slot = 3
SpillProperty: timeStamp (flags = NON_MODIFIABLE), index = 0

•  Immutable	
  
•  Copy	
  on	
  write	
  when	
  any	
  aspect	
  
changes	
  
•  Used	
  for	
  reference	
  guards	
  for	
  almost	
  
all	
  invokedynamic	
  sites	
  
Field	
  Representa*on	
  
var scopeVar;

function f() {
scopeVar &= 17;
}
	
  	
  	
  	
  	
  	
  
Field	
  Representa*on	
  
var scopeVar;

function f() {
scopeVar &= 17;
}
	
  	
  	
  	
  	
  	
  
1.  Load	
  scope	
  var	
  (getfield),	
  stored	
  as	
  Object,	
  is	
  a	
  
java.lang.Integer
2.  Coerce	
  to	
  int	
  (unbox	
  from	
  java.lang.Integer)	
  
3.  Execute	
  logical	
  and	
  (iand)	
  
4.  Coerce	
  result	
  to	
  object	
  (box	
  to	
  java.lang.Integer)	
  
5.  putfield	
  result	
  
Field	
  Representa*on	
  
var scopeVar;

function f() {
scopeVar &= 17;
}
	
  	
  	
  	
  	
  	
  
1.  Load	
  scope	
  var	
  (getfield),	
  stored	
  as	
  
java.lang.Integer
2.  Coerce	
  to	
  int	
  (unbox	
  from	
  java.lang.Integer)	
  
3.  Execute	
  logical	
  and	
  	
  
4.  Coerce	
  result	
  to	
  object	
  (box	
  to	
  java.lang.Integer)	
  
5.  putfield	
  result	
  
Field	
  Representa*on	
  
public abstract class ScriptObject 

implements PropertyAccess {

protected Object[] spillObjects;

long spillPrimitives;

// most guards are a ref comparison on map 

private PropertyMap map;
}

public JO$4 extends ScriptObject {
private Object o0, o1, o2, o3;
p4;
}
	
  	
  	
  	
  	
  	
  
	
  
	
  
Field	
  Representa*on	
  
public abstract class ScriptObject 

implements PropertyAccess {

protected Object[] spillObjects;

protected long[] spillPrimitives; s

// most guards are a ref comparison on map 

private PropertyMap map;
}

public JO$4 extends ScriptObject {
private Object o0, o1, o2, o3;
private long j0, j1, j2, j3;, p2, p3, p4;
}
Field	
  Representa*on	
  
“EWW!	
  Fat	
  pointers”	
  
public abstract class ScriptObject 

implements PropertyAccess {

protected Object[] spillObjects;

protected long[] spillPrimitives; s

// most guards are a ref comparison on map 

private PropertyMap map;
}

public JO$4 extends ScriptObject {
private Object o0, o1, o2, o3;
private long j0, j1, j2, j3;, p2, p3, p4;
}
Field	
  Representa*on	
  
obj.j = (long)x; //int
obj.j = x; //long
obj.j = Double.doubleToLongBits(x); //double
obj.o = x; //object
return (int)obj.j;
 //int
return obj.j; //long
return Double.longBitsToDouble(obj.j); //double
return obj.o; //object
SePers	
  
GePers	
  
Property	
  Maps	
  and	
  Types	
  
•  Immutable	
  
•  Copy	
  on	
  write	
  when	
  any	
  aspect	
  changes	
  
•  Used	
  for	
  reference	
  guards	
  for	
  almost	
  all	
  
invokedynamic	
  sites	
  
PropertyMap

AccessorProperty: red (flags = 0) slot = 0, type = int

AccessorProperty: green (flags = 0) slot = 1, type = int
AccessorProperty: blue (flags = 0) slot = 3, type = int
SpillProperty: timeStamp (flags = NON_MODIFIABLE), index = 0,
type = object
Property	
  Maps	
  and	
  Types	
  
PropertyMap

AccessorProperty: red (flags = 0) type=int

AccessorProperty: green (flags = 0) type=int
AccessorProperty: blue (flags = 0) type=object
SpillProperty: timeStamp (flags = NON_MODIFIABLE),type=object
•  Immutable	
  
•  Copy	
  on	
  write	
  when	
  any	
  aspect	
  changes	
  
•  INCLUDING	
  FIELD	
  TYPE	
  
•  Used	
  for	
  reference	
  guards	
  for	
  almost	
  all	
  
invokedynamic	
  sites	
  
•  INCLUDING	
  FIELD	
  GETTERS	
  AND	
  SETTERS	
  
PropertyMap

AccessorProperty: red (flags = 0) slot = 0, type = int

AccessorProperty: green (flags = 0) slot = 1, type = int
AccessorProperty: blue (flags = 0) slot = 3, type = int
SpillProperty: timeStamp (flags = NON_MODIFIABLE), index = 0,
type = object
Field	
  Representa*on	
  
var scopeVar;

function f() {
scopeVar &= 17;
}
	
  	
  	
  	
  	
  	
  
1.  Load	
  scope	
  var	
  (getfield),	
  stored	
  as	
  
java.lang.Integer
2.  Coerce	
  to	
  int	
  (unbox	
  from	
  java.lang.Integer)	
  
3.  Execute	
  logical	
  and	
  (iand)	
  
4.  Coerce	
  result	
  to	
  object	
  (box	
  to	
  java.lang.Integer)	
  
5.  putfield	
  result	
  
Field	
  Representa*on	
  
var scopeVar;

function f() {
scopeVar &= 17;
}
	
  	
  	
  	
  	
  	
  
1.  Load	
  scope	
  var	
  (getfield),	
  stored	
  as	
  	
  
	
  	
  	
  	
  	
  	
  	
  long
1.  Coerce	
  to	
  int	
  (l2i)	
  
2.  Execute	
  logical	
  and	
  (iand)	
  
3.  Coerce	
  to	
  long	
  (i2l)	
  
4.  putfield	
  result	
  
Field	
  Representa*on	
  
•  BePer	
  representa*on?	
  
– Unsafe?	
  
– Needs	
  some	
  JVM	
  magic,	
  anyway	
  
– Test	
  implementa*on:	
  
sun.misc.TaggedArray
– Object	
  shape	
  change	
  on	
  GC?	
  
– Let’s	
  form	
  an	
  expert	
  group!	
  
	
  
	
  	
  
Closing	
  the	
  circle:	
  	
  
	
  Op*mis*c	
  Buil*ns	
  	
  
Op*mis*c	
  buil*ns	
  
	
  	
  
/**
* ECMA 15.4.4.7 Array.prototype.push (args...)
*
* @param self self reference
* @param args arguments to push
* @return array length after pushes
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object push(final Object self, final Object... args) {
try {
final ScriptObject sobj = (ScriptObject)self;

if (bulkable(sobj) && sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
final ArrayData newData = sobj.getArray().push(true, args);
sobj.setArray(newData);
return newData.length();
}

long len = JSType.toUint32(sobj.getLength());
for (final Object element : args) {
sobj.set(len++, element, true);
}
sobj.set("length", len, true);

return len;
} catch (final ClassCastException | NullPointerException e) {
throw typeError(Context.getGlobal(), e, "not.an.object", ScriptRuntime.safeToString(self));
}
}
	
  	
  
Relinking	
  Callsites	
  
•  Can	
  now	
  be	
  done	
  with	
  Excep*ons	
  as	
  well	
  as	
  guards	
  or	
  SwitchPoints	
  
•  For	
  example:	
  con*nuous	
  arrays	
  
–  Previously	
  done	
  with	
  mul*ple	
  guards	
  
•  array[x] & 17
•  Array	
  gePer	
  links	
  to:	
  

try {

 
//combinator – not real code
return ((ContinuousArrayData)scriptObject.

getArrayData()).

 
getElementGetter(int.class).

 
 
get(index); //turns AIOOBE to CCE
} catch (ClassCastException e) {

//relink
}
"	
  
Op*mis*c	
  buil*ns	
  
	
  	
  
/**
* ECMA 15.4.4.7 Array.prototype.push (args...)
*
* @param self self reference
* @param args arguments to push
* @return array length after pushes
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object push(final Object self, final Object... args) {
try {
final ScriptObject sobj = (ScriptObject)self;

if (bulkable(sobj) && sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
final ArrayData newData = sobj.getArray().push(true, args);
sobj.setArray(newData);
return newData.length();
}

long len = JSType.toUint32(sobj.getLength());
for (final Object element : args) {
sobj.set(len++, element, true);
}
sobj.set("length", len, true);

return len;
} catch (final ClassCastException | NullPointerException e) {
throw typeError(Context.getGlobal(), e, "not.an.object", ScriptRuntime.safeToString(self));
}
}
	
  	
  
Op*mis*c	
  buil*ns	
  
	
  	
  

// pre: linker checks that callsite argument matches

@SpecializedFunction(guard=SpecializedFunction.Guard.CLASSCAST_EXCEPTION_CONTINUOUS_ARRAY)
public static long push(final Object self, final int arg) {

 try { 
 

 
return ((ContinuousArrayData)self).getArray()).push(arg);

 } catch (final NullPointerException e) {

 
//fallthru
} 

 throw new ClassCastException();
 }
Op*mis*c	
  buil*ns
•  Lots	
  of	
  candidates	
  
–  Array
•  push, pop, shift, unshift, length
–  String
•  charAt, charCodeAt, length
–  Number, Math
–  Function.apply to	
  	
  Function.call
–  …
•  We	
  can	
  use	
  the	
  same	
  recompila*on	
  framework	
  
for	
  na*ve	
  methods	
  as	
  for	
  JavaScript	
  methods	
  
An*paPern	
  that	
  JS	
  programmers	
  love	
  
var Class = {
create: function() {
return function() { //vararg
this.initialize.apply(this, arguments);
}
}
};
Color = Class.create();

Color.prototype = {
red: 0, green: 0, blue: 0,

initialize: function(r, g, b) {

 this.red = r;

 this.green = g;

 this.blue = b;
},
toString: function() {
return this.red + “ “ 

 
+ this.green + “ “ 

 
+ this.blue; 
} 
}
print(new Color(0xff, 0xee, 0xcc));
Other	
  op*miza*ons	
  
Par*al	
  Evalua*on	
  
for (var i = 0; i < x.length; i++) {

//x is loop invariant
)

•  x	
  can	
  use	
  MethodHandle.constant	
  as	
  an	
  indy	
  
gePer.	
  
•  We	
  can	
  use	
  a	
  SwitchPoint	
  to	
  invalidate	
  it,	
  
given	
  that	
  x	
  is	
  modified	
  in	
  the	
  scope	
  
•  Either	
  forbid	
  this	
  callsite	
  from	
  being	
  constant	
  
again,	
  or	
  allow	
  n	
  retries	
  
•  Or	
  try	
  with	
  a	
  receiver	
  guard	
  
U*lize	
  java.nio.ByteBuffer
•  Anyone	
  using	
  WebGL/ECMA	
  6	
  TypedArrays	
  
can	
  get	
  near-­‐na*ve	
  performance	
  
•  java.nio.ByteBuffer	
  
•  5-­‐10x	
  microbenchmark	
  improvements	
  
•  Exported	
  BufferArray	
  to	
  avatar.js	
  
JVM	
  /	
  JDK	
  op*miza*ons	
  
•  BePer	
  type	
  checking	
  
•  Math	
  intrinsics	
  
•  Inlining	
  modifica*on	
  
•  Experiments	
  with	
  par*al	
  escape	
  analysis	
  /	
  boxing	
  
removal	
  
•  Uncommon	
  trap	
  placement	
  
•  java.lang.invoke
–  Had	
  to	
  significantly	
  beef	
  up	
  
MethodHandles.catchException and	
  many	
  more
•  	
  …	
  
There’s	
  SO	
  MUCH	
  MORE	
  I	
  WANT	
  TO	
  
TELL	
  YOU	
  
The	
  cost	
  of	
  all	
  this:	
  warmup	
  
Warmup	
  
•  The	
  need	
  to	
  recompile	
  methods	
  has	
  increased	
  
warmup	
  *me	
  
•  Tricks	
  
– RewriteException	
  contains	
  scope	
  
•  More	
  types	
  are	
  known	
  when	
  recompiling	
  
– Heuris*cs	
  
– Lazy	
  compila*on	
  
function gcd(x, y) {
var a = x;
var b = y;
while (a != b) {

 
if (a > b) {

 
 
a = a - b;

 
} else {

 
 
b = b - a;

 
} 

}
return a;
}

gcd(x, y);
Compiles	
  gcd	
  
function gcd(x, y) {
var a = x;
var b = y;
while (a != b) {

 
if (a > b) {

 
 
a = a - b;

 
} else {

 
 
b = b - a;

 
} 

}
return a;
}

gcd(x, y);
Compiles	
  gcd	
  
function gcd(x, y) {
var a = x;
var b = y;
while (a != b) {

 
if (a > b) {

 
 
a = a - b;

 
} else {

 
 
b = b - a;

 
} 

}
return a;
}

Does	
  not	
  compile	
  gcd	
  
Lazy	
  Compila*on	
  
•  Methods	
  are	
  only	
  compiled	
  on	
  demand	
  
•  At	
  link	
  *me	
  
– if	
  no	
  matching	
  signature	
  exists,	
  compile	
  one,	
  as	
  
specific	
  as	
  possible	
  
– If	
  matching	
  signature	
  does	
  exist,	
  try	
  to	
  compile	
  an	
  
even	
  more	
  specific	
  one	
  
•  Code	
  quality	
  is	
  the	
  same	
  as	
  eager	
  compila*on	
  
– Scope	
  depths	
  are	
  maintained	
  
Warmup	
  
•  Tricks	
  (for	
  run	
  2)	
  
– Persistent	
  code	
  cache	
  (--persistent-code-
cache)	
  
– Op*mis*c	
  type	
  informa*on	
  also	
  cached	
  to	
  disk	
  
– TODO:	
  parsed	
  script	
  for	
  par*al	
  recompila*on	
  
•  Reduces	
  the	
  second	
  run	
  to	
  a	
  very	
  fast	
  startup	
  
– …	
  not	
  the	
  first	
  run,	
  however	
  
The	
  Future	
  
 
	
  
Profiling	
  and	
  Java	
  Flight	
  Recorder	
  
•  A	
  JFR	
  “Nashorn”	
  buPon	
  
•  JFR	
  event	
  produc*on	
  is	
  simple,	
  low	
  overhead,	
  
and	
  doesn’t	
  require	
  closing	
  the	
  source	
  base	
  
•  Unique	
  possibility	
  to	
  create	
  a	
  JavaScript	
  
profiler	
  that	
  no	
  one	
  else	
  can	
  do	
  
Profiling	
  and	
  Java	
  Flight	
  Recorder	
  
•  A	
  Nashorn	
  JavaScript	
  method	
  is	
  bytecode	
  
•  It	
  has	
  local	
  variable	
  tables,	
  names,	
  line	
  
numbers	
  
•  Fits	
  100%	
  into	
  the	
  JFR	
  framework	
  already	
  
•  (IDE	
  plugin	
  for	
  source	
  level	
  mapping)	
  
•  I	
  already	
  use	
  JFR	
  every	
  day	
  with	
  this	
  
JFR	
  events	
  –	
  the	
  sky’s	
  the	
  limit	
  
•  Megamorphic	
  callsite	
  
•  Subop*mal	
  object	
  shape	
  
•  Callsite	
  hits,	
  misses,	
  values	
  
•  Scope	
  access	
  
•  Fast	
  scope	
  access	
  
•  with	
  entry/exit,	
  eval,	
  an*paPerns	
  
•  Split	
  methods	
  
•  Excep*ons	
  
•  Relink	
  with	
  relink	
  reason	
  
•  Assump*on	
  made	
  
•  Assump*on	
  invalidated	
  	
  
•  Code	
  pipeline	
  reuse	
  	
  
•  Timing	
  	
  
•  Specialized	
  method	
  invoca*on	
  	
  
•  Type	
  widening	
  
•  Method	
  invalida*on	
  
•  Boxing	
  /	
  unboxing	
  	
  
•  Non-­‐trivial	
  callsites	
  
•  Use	
  of	
  arguments	
  	
  
•  Use	
  of	
  callee	
  
•  Code	
  spliung	
  
•  Class	
  crea*on	
  
•  Versions	
  of	
  compiled	
  func*ons	
  	
  
•  Code	
  cache	
  store/reuse	
  	
  
•  Array	
  meta	
  informa*on	
  	
  
•  Compila*on	
  *me	
  	
  
•  Slow	
  source	
  lines	
  	
  
•  Byte	
  code	
  size	
  
•  IR	
  size	
  histograms	
  	
  
•  Index	
  access	
  on	
  non-­‐arrays	
  
•  Non-­‐index	
  access	
  on	
  arrays	
  
•  …	
  
The	
  Future	
  
•  Avatar	
  
•  the	
  JVM	
  	
  
•  the	
  JDK	
  	
  
•  Nashorn	
  	
  
•  the	
  Hardware	
  (?)	
  
0	
  
1	
  
2	
  
3	
  
4	
  
5	
  
6	
  
7	
  
rhino	
  
nashorn	
  jdk8	
  
nashorn	
  jdk9	
  
The	
  Future	
  
Let	
  Nashorn	
  be	
  the	
  intelligent	
  dynamic	
  language	
  
execu*on	
  framework	
  for	
  the	
  JVM,	
  regardless	
  of	
  
frontend.	
  
Q	
  &	
  A?	
  
Give	
  us	
  your	
  benchmarks,	
  your	
  experiments,	
  your	
  hacks,	
  	
  
your	
  patch	
  sets,	
  we’d	
  love	
  your	
  help!	
  
Extra	
  Slides	
  awer	
  this	
  point	
  
Relinking	
  Callsites	
  
•  An	
  indy	
  callsite	
  is	
  a	
  subclass	
  of	
  
GuardedInvocation
•  Invalida*on	
  mechanisms:	
  
– Op*onal	
  guard	
  
– Op*onal	
  SwitchPoint
Relinking	
  Callsites	
  
•  An	
  indy	
  callsite	
  is	
  a	
  subclass	
  of	
  
GuardedInvocation
•  Invalida*on	
  mechanisms:	
  
– Op*onal	
  guard	
  
– Op*onal	
  SwitchPoints	
  (0	
  …	
  n)	
  
– Op*onal	
  Excep*on	
  
•  Typically	
  ClassCastException
/**
* Constructor for a rewrite exception thrown from an optimistic function.
*
* @param e the {@link UnwarrantedOptimismException} that triggered this exception.
* @param byteCodeSlots contents of local variable slots at the time of rewrite at the program point
* @param byteCodeSymbolNames the names of the variables in the {@code byteCodeSlots} parameter. 
*
* The array might have less elements, and some elements might be unnamed (the name can be null). The 
* information is provided in an effort to assist evaluation of expressions for their types by the 
* compiler doing the deoptimizing recompilation,
* and can thus be incomplete - the more complete it is, the more expressions can be evaluated by the 
* compiler, and the more unnecessary deoptimizing compilations can be avoided.
*
* @return a new rewrite exception
*/ 

public static RewriteException create(final UnwarrantedOptimismException e,
final Object[] byteCodeSlots,
final String[] byteCodeSymbolNames);
Linker	
  generates	
  “restOf”	
  method,	
  which	
  is	
  idenLcal	
  but	
  takes	
  only	
  
RewriteExcepLon	
  as	
  argument,	
  rewrites	
  the	
  frame	
  state	
  and	
  jumps	
  to	
  
the	
  corresponding	
  execuLon	
  point	
  unLl	
  “restOf”	
  method	
  has	
  
executed.	
  Old	
  method	
  is	
  invalidated.	
  Next	
  call	
  will	
  generate	
  a	
  wider	
  
version.	
  
apply	
  to	
  call
return function() { //vararg
this.initialize.apply(this, arguments);
}

public static L:3(ScriptFunction;Object;[Object;)Object;
aload 2 // args array
aload 0 // callee
iconst_0 // actual number of declared params
invokestatic Global.allocateArguments([Object;Object;I)[Object;
astore 3
aload 1
invokedynamic get:initialize(Object;)Object; 
dup
invokedynamic get:apply(Object;)Object; 
swap
aload 1
aload 3
invokedynamic dyn:call(Object;Object;Object;Object;)Object; 
pop
getstatic ScriptRuntime.UNDEFINED
areturn
	
  
return function() { //vararg
this.initialize.apply(this, arguments);
}

public static L:3(ScriptFunction;Object;III)Object;
aload 1
invokedynamic get:initialize(Object;)Object;
dup
invokedynamic get:apply(Object;)Object; //really loads “call”
swap
aload 1
iload 2
iload 3
iload 4
invokedynamic dyn:call(Object;Object;Object;III)Object;
pop
getstatic ScriptRuntime.UNDEFINED;
areturn 
apply	
  to	
  call
return function() { //vararg
this.initialize.apply(this, arguments);
}

public static L:3(ScriptFunction;Object;III)Object;
aload 1
invokedynamic get:initialize(Object;)Object;
dup
invokedynamic get:apply(Object;)Object; //really loads “call”
swap
aload 1
iload 2
iload 3
iload 4
invokedynamic dyn:call(Object;Object;Object;III)Object;
pop
getstatic ScriptRuntime.UNDEFINED;
areturn 
apply	
  to	
  call
local :callee L0 L1 0 ScriptFunction;
local :this L0 L1 1 Object;
local :xarg0 L0 L1 2 I
local :xarg1 L0 L1 3 I
local :xarg2 L0 L1 4 I
Function.prototype.call = function() {
throw “This is a JavaScript! No performance for you!”;
}
SwitchPoint	
  based	
  dynamic	
  invalida*on	
  –	
  same	
  mechanism	
  as	
  everewhere	
  else	
  
apply	
  to	
  call

Mais conteúdo relacionado

Mais procurados

JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesCharles Nutter
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Charles Nutter
 
Dockerize it! @ Codemotion 2016 in Rome
Dockerize it! @ Codemotion 2016 in RomeDockerize it! @ Codemotion 2016 in Rome
Dockerize it! @ Codemotion 2016 in RomeAlessandro Nadalin
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for RubyHiroshi SHIBATA
 
Diagnosing Your Application on the JVM
Diagnosing Your Application on the JVMDiagnosing Your Application on the JVM
Diagnosing Your Application on the JVMStaffan Larsen
 
A tour of Java and the JVM
A tour of Java and the JVMA tour of Java and the JVM
A tour of Java and the JVMAlex Birch
 
Complex Made Simple: Sleep Better With TorqueBox
Complex Made Simple: Sleep Better With TorqueBoxComplex Made Simple: Sleep Better With TorqueBox
Complex Made Simple: Sleep Better With TorqueBoxLance Ball
 
Exploring the Titanium CLI - Codestrong 2012
Exploring the Titanium CLI - Codestrong 2012Exploring the Titanium CLI - Codestrong 2012
Exploring the Titanium CLI - Codestrong 2012Chris Barber
 
Integrating microservices with apache camel on kubernetes
Integrating microservices with apache camel on kubernetesIntegrating microservices with apache camel on kubernetes
Integrating microservices with apache camel on kubernetesClaus Ibsen
 
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...Nikita Lipsky
 
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013Chris Barber
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 
Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019
Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019
Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019Jakarta_EE
 
Jfokus 2016 - A JVMs Journey into Polyglot Runtimes
Jfokus 2016 - A JVMs Journey into Polyglot RuntimesJfokus 2016 - A JVMs Journey into Polyglot Runtimes
Jfokus 2016 - A JVMs Journey into Polyglot RuntimesCharlie Gracie
 
Migrate to JRuby
Migrate to JRubyMigrate to JRuby
Migrate to JRubyIan Yang
 
meetPHP#8 - PHP startups prototypes
meetPHP#8 - PHP startups prototypesmeetPHP#8 - PHP startups prototypes
meetPHP#8 - PHP startups prototypesMax Małecki
 
Ahead-Of-Time Compilation of Java Applications
Ahead-Of-Time Compilation of Java ApplicationsAhead-Of-Time Compilation of Java Applications
Ahead-Of-Time Compilation of Java ApplicationsNikita Lipsky
 
Tackling non-determinism in Hadoop - Testing and debugging distributed system...
Tackling non-determinism in Hadoop - Testing and debugging distributed system...Tackling non-determinism in Hadoop - Testing and debugging distributed system...
Tackling non-determinism in Hadoop - Testing and debugging distributed system...Akihiro Suda
 

Mais procurados (20)

JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
 
Dockerize it! @ Codemotion 2016 in Rome
Dockerize it! @ Codemotion 2016 in RomeDockerize it! @ Codemotion 2016 in Rome
Dockerize it! @ Codemotion 2016 in Rome
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for Ruby
 
Diagnosing Your Application on the JVM
Diagnosing Your Application on the JVMDiagnosing Your Application on the JVM
Diagnosing Your Application on the JVM
 
A tour of Java and the JVM
A tour of Java and the JVMA tour of Java and the JVM
A tour of Java and the JVM
 
Complex Made Simple: Sleep Better With TorqueBox
Complex Made Simple: Sleep Better With TorqueBoxComplex Made Simple: Sleep Better With TorqueBox
Complex Made Simple: Sleep Better With TorqueBox
 
Exploring the Titanium CLI - Codestrong 2012
Exploring the Titanium CLI - Codestrong 2012Exploring the Titanium CLI - Codestrong 2012
Exploring the Titanium CLI - Codestrong 2012
 
Integrating microservices with apache camel on kubernetes
Integrating microservices with apache camel on kubernetesIntegrating microservices with apache camel on kubernetes
Integrating microservices with apache camel on kubernetes
 
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
 
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
 
Event machine
Event machineEvent machine
Event machine
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
Java on the Mainframe
Java on the MainframeJava on the Mainframe
Java on the Mainframe
 
Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019
Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019
Kubernetes Native Java and Eclipse MicroProfile | EclipseCon Europe 2019
 
Jfokus 2016 - A JVMs Journey into Polyglot Runtimes
Jfokus 2016 - A JVMs Journey into Polyglot RuntimesJfokus 2016 - A JVMs Journey into Polyglot Runtimes
Jfokus 2016 - A JVMs Journey into Polyglot Runtimes
 
Migrate to JRuby
Migrate to JRubyMigrate to JRuby
Migrate to JRuby
 
meetPHP#8 - PHP startups prototypes
meetPHP#8 - PHP startups prototypesmeetPHP#8 - PHP startups prototypes
meetPHP#8 - PHP startups prototypes
 
Ahead-Of-Time Compilation of Java Applications
Ahead-Of-Time Compilation of Java ApplicationsAhead-Of-Time Compilation of Java Applications
Ahead-Of-Time Compilation of Java Applications
 
Tackling non-determinism in Hadoop - Testing and debugging distributed system...
Tackling non-determinism in Hadoop - Testing and debugging distributed system...Tackling non-determinism in Hadoop - Testing and debugging distributed system...
Tackling non-determinism in Hadoop - Testing and debugging distributed system...
 

Semelhante a Lagergren jvmls-2014-final

Drools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentationDrools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentationMark Proctor
 
Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)
Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)
Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)OpenBlend society
 
Immutable infrastructure:觀念與實作 (建議)
Immutable infrastructure:觀念與實作 (建議)Immutable infrastructure:觀念與實作 (建議)
Immutable infrastructure:觀念與實作 (建議)William Yeh
 
A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9Marcus Lagergren
 
JVMs in Containers - Best Practices
JVMs in Containers - Best PracticesJVMs in Containers - Best Practices
JVMs in Containers - Best PracticesDavid Delabassee
 
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
차세대컴파일러, VM의미래: 애플 오픈소스 LLVMJung Kim
 
[JOI] TOTVS Developers Joinville - Java #1
[JOI] TOTVS Developers Joinville - Java #1[JOI] TOTVS Developers Joinville - Java #1
[JOI] TOTVS Developers Joinville - Java #1Rubens Dos Santos Filho
 
Running JavaScript Efficiently in a Java World
Running JavaScript Efficiently in a Java WorldRunning JavaScript Efficiently in a Java World
Running JavaScript Efficiently in a Java Worldirbull
 
Not Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsNot Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsKonrad Malawski
 
Java code coverage with JCov. Implementation details and use cases.
Java code coverage with JCov. Implementation details and use cases.Java code coverage with JCov. Implementation details and use cases.
Java code coverage with JCov. Implementation details and use cases.Alexandre (Shura) Iline
 
Javantura 2014 - Java 8 JavaScript Nashorn
Javantura 2014 - Java 8 JavaScript NashornJavantura 2014 - Java 8 JavaScript Nashorn
Javantura 2014 - Java 8 JavaScript NashornMiroslav Resetar
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysManuel Bernhardt
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureQAware GmbH
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLMario-Leander Reimer
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaWO Community
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 

Semelhante a Lagergren jvmls-2014-final (20)

Jax keynote
Jax keynoteJax keynote
Jax keynote
 
Drools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentationDrools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentation
 
Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)
Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)
Byteman and The Jokre, Sanne Grinovero (JBoss by RedHat)
 
Immutable infrastructure:觀念與實作 (建議)
Immutable infrastructure:觀念與實作 (建議)Immutable infrastructure:觀念與實作 (建議)
Immutable infrastructure:觀念與實作 (建議)
 
A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9
 
JVMs in Containers
JVMs in ContainersJVMs in Containers
JVMs in Containers
 
JVMs in Containers - Best Practices
JVMs in Containers - Best PracticesJVMs in Containers - Best Practices
JVMs in Containers - Best Practices
 
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
 
[JOI] TOTVS Developers Joinville - Java #1
[JOI] TOTVS Developers Joinville - Java #1[JOI] TOTVS Developers Joinville - Java #1
[JOI] TOTVS Developers Joinville - Java #1
 
Running JavaScript Efficiently in a Java World
Running JavaScript Efficiently in a Java WorldRunning JavaScript Efficiently in a Java World
Running JavaScript Efficiently in a Java World
 
Not Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsNot Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabs
 
Java code coverage with JCov. Implementation details and use cases.
Java code coverage with JCov. Implementation details and use cases.Java code coverage with JCov. Implementation details and use cases.
Java code coverage with JCov. Implementation details and use cases.
 
Javantura Zagreb 2014 - Nashorn - Miroslav Rešetar
Javantura Zagreb 2014 - Nashorn - Miroslav RešetarJavantura Zagreb 2014 - Nashorn - Miroslav Rešetar
Javantura Zagreb 2014 - Nashorn - Miroslav Rešetar
 
Javantura 2014 - Java 8 JavaScript Nashorn
Javantura 2014 - Java 8 JavaScript NashornJavantura 2014 - Java 8 JavaScript Nashorn
Javantura 2014 - Java 8 JavaScript Nashorn
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventure
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPL
 
Splunking the JVM
Splunking the JVMSplunking the JVM
Splunking the JVM
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with Scala
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 

Último

英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfIdiosysTechnologies1
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 

Último (20)

英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdf
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 

Lagergren jvmls-2014-final

  • 1. Towards  na*ve  performance  with   dynamic  languages  on  the  JVM   Marcus  Lagergren,  Oracle  
  • 2. Towards  na*ve  performance  with   dynamic  languages  on  the  JVM   Marcus  Lagergren,  Oracle   How  far  does  invokedynamic  take  us?  
  • 3. Towards  na*ve  performance  with   dynamic  languages  on  the  JVM   Marcus  Lagergren,  Oracle   How  far  does  invokedynamic  take  us?   Pre$y  far  actually!  
  • 4. The  Legal  Slide   "THE FOLLOWING IS INTENDED TO OUTLINE OUR GENERAL PRODUCT DIRECTION. IT IS INTENDED FOR INFORMATION PURPOSES ONLY, AND MAY NOT BE INCORPORATED INTO ANY CONTRACT. IT IS NOT A COMMITMENT TO DELIVER ANY MATERIAL, CODE, OR FUNCTIONALITY, AND SHOULD NOT BE RELIED UPON IN MAKING PURCHASING DECISION. THE DEVELOPMENT, RELEASE, AND TIMING OF ANY FEATURES OR FUNCTIONALITY DESCRIBED FOR ORACLE'S PRODUCTS REMAINS AT THE SOLE DISCRETION OF ORACLE."  
  • 5. Who  am  I?   @lagergren    
  • 6. Agenda   •  Nashorn  summary   •  The  last  nine  months  of  Nashorn  and   invokedynamic  performance  work   •  How  did  we  do  it?     •  The  future  
  • 7. Nashorn   •  Part  of  JDK  8   – 100%  ECMA  compliant  JavaScript  run*me  wriPen   in  Java   •  ECMA  5.1  support   – Limited  ECMA  6  support  (8u40)   •  invokedynamic  based   •  Generates  bytecode   – Currently  no  AST  interpreta*on  
  • 8. Nashorn  –  release  schedule   •  Java  8     – First  version  for  public  consump*on  
  • 9. Nashorn  –  release  schedule   •  Java  8     – First  version  for  public  consump*on   •  Java  8u20   – Security  fixes  and  several  JIT  /  JDK  improvements  
  • 10. Nashorn  –  release  schedule   •  Java  8     – First  version  for  public  consump*on   •  Java  8u20   – Security  fixes  and  several  JIT  /  JDK  improvements   •  Java  8u40   – Performance  release  
  • 11. Nashorn  –  release  schedule   •  Java  8     – First  version  for  public  consump*on   •  Java  8u20   – Security  fixes  and  several  JIT  /  JDK  improvements   •  Java  8u40   – Performance  release   •  Java  9    
  • 12. Nashorn  –  release  schedule   •  Java  8     – First  version  for  public  consump*on   •  Java  8u20   – Security  fixes  and  several  JIT  /  JDK  improvements   •  Java  8u40   – Performance  release   •  Java  9    
  • 13. Evangelist  Blurb   “Nashorn  is  a  really  fast  100%  JS  compilant   invokedynamic  based  JavaScript  run*me  wriPen   in  Java.  It  runs  on  top  of  the  JVM”  
  • 14. …  or  maybe?   “Nashorn  is  a  run*me  for  dynamic  languages  on   the  JVM.  Nashorn  takes  away  the  pain  and   performance  loss  of  bridging  the  gap  between   language  and  bytecode.  Types,  objects  and  code   are  automa*cally  adapted  to  be  an  op*mal  fit  in   the  JVM  mould”  
  • 16. JavaScript   “Once  you  admit  that  EVERYTHING  IS  TERRIBLE,      the  universe  opens  infinitely  many  doors  for            you...    TO  TERRIBLE.”                      -­‐  Jerry  Kuch  
  • 17. Where  were  we  last  October?   Octane  Benchmark  r31   0   0.2   0.4   0.6   0.8   1   1.2   rhino   nashorn  jdk8  
  • 18. Where  are  we  today?   Octane  Benchmark  r31   0   1   2   3   4   5   6   7   rhino   nashorn  jdk8   nashorn  jdk9  
  • 19. …  against  v8   Octane  Benchmark  r31   0   2   4   6   8   10   12   rhino   nashorn  jdk8   nashorn  jdk9   v8  
  • 20. v8  bleeding  edge…   Octane  Benchmark  r31   0   2   4   6   8   10   12   14   rhino   nashorn  jdk8   nashorn  jdk9   v8   v8  latest  
  • 22. avatar.js   •  Project  Avatar   – HTTP  benchmark   – REST  benchmark   •  Comparable  to  v8  /  na*ve  performance   •  8u40  will  deliver  plenty  of  improvements   •  Use  of  exposed  mechanisms   – BufferArrayData  
  • 23. avatar.js   •  Project  Avatar   – HTTP  benchmark   – REST  benchmark   •  Comparable  to  v8  /  na*ve  performance   •  8u40  will  deliver  plenty  of  improvements   •  Use  of  exposed  mechanisms   – BufferArrayData  
  • 26. Op*mis*c  Type  Run*me  Architecture   [hPp://openjdk.java.net/jeps/196]  
  • 27. Just  compile  to  bytecode!   •  “The  JVM  is  technically  advanced  and  has  man   decades  of  JIT  op*miza*ons”   •  “The  JVM  magically  JITs  arbitrary  bytecode  to   fast  na*ve  code”  
  • 28. Just  compile  to  bytecode!   •  “The  JVM  is  technically  advanced  and  has  man   decades  of  JIT  op*miza*ons”   •  “The  JVM  magically  JITs  arbitrary  bytecode  to   fast  na*ve  code”   •  Nope  :-­‐(  
  • 29.
  • 30. function gcd(x, y) { var a = x; var b = y; while (a != b) { if (a > b) { a = a - b; } else { b = b - a; } } return a; } gcd(x, y); GCD  
  • 31. GCD  –  Naïve  &  JS  Compliant   public static gcd(Object;Object;Object;)Object; aload 1 astore 4 aload 2 astore 5 goto L2 aload 4 aload 5 invokedynamic GT:ZOO_Z(Object;Object;)Z; ifeq L4 aload 4 invokestatic JSType.toNumber(Object;)D aload 5 invokestatic JSType.toNumber(Object;)D dsub invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double; astore 4 goto L2 aload 5 invokestatic JSType.toNumber(Object;)D aload 4 invokestatic JSType.toNumber(Object;)D dsub invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double; astore 5 aload 4 aload 5 invokedynamic NE:ZOO_Z(Object;Object;)Z ifne L3 aload 4 areturn
  • 32. GCD  –  vs  Ideal   public static gcd(Object;Object;Object;)Object; aload 1 astore 4 aload 2 astore 5 goto L2 aload 4 aload 5 invokedynamic GT:ZOO_Z(Object;Object;)Z; ifeq L4 aload 4 invokestatic JSType.toNumber(Object;)D aload 5 invokestatic JSType.toNumber(Object;)D dsub invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double; astore 4 goto L2 aload 5 invokestatic JSType.toNumber(Object;)D aload 4 invokestatic JSType.toNumber(Object;)D dsub invokestatic java/lang/Double.valueOf(D)Ljava/lang/Double; astore 5 aload 4 aload 5 invokedynamic NE:ZOO_Z(Object;Object;)Z ifne L3 aload 4 areturn public static gcd(Object;II)I iload 1 istore 3 iload 2 istore 4 iload 3 iload 4 if_icmpeq L10 iload 3 iload 4 if_icmple L12 iload 3 iload 4 isub istore 3 goto L14 iload 4 iload 3 isub istore 4 goto L9 iload 3 ireturn
  • 33. Op*mis*c  Types   •  Factor  150x  difference  in  execu*on  speed   between  the  two   •  “Generate  Java-­‐like  bytecode”  
  • 34.
  • 35. Op*mis*c  Types   •  Generate  as  op*mis*c  a  func*on  as  possible   •  Surround  op*mis*c  opera*ons  with  excep*on   handlers   •  When  a  type  is  too  narrow   – Store  frame  state  (no  bytecode  stack)   – Take  a  con*nua*on  and  finish  method   – Tell  linker  to  regenerate  more  conserva*vely  
  • 36. Op*mis*c  Types   long   double   Object  (pessimis*c)  int    
  • 37. Implementa*on   function f() { return x * y; // x,y in scope }
  • 38. public static f(ScriptFunction;Object;)D aload 0 invokevirtual ScriptFunction.getScope()LScriptObject; astore 2 // store scope in slot 2 aload 2 // load scope invokedynamic get:x(Object;)Object; aload 2 // load scope invokedynamic get:y(Object;)Object; swap invokestatic JSType.toNumber(Object;)D dup2_x1 pop2 invokestatic JSType.toNumber(Object;)D dmul dreturn  
  • 39. public static f(ScriptFunction;Object;)I aload 0 invokevirtual ScriptFunction.getScope()ScriptObject; astore 2 // store scope in slot 2 aload 2 invokedynamic get:x(Object;)I istore 3 iload 3 aload 2 invokedynamic get:y(Object;)I invokedynamic imul(II)I ireturn  
  • 40. public static f(ScriptFunction;Object;)I aload 0 invokevirtual ScriptFunction.getScope()ScriptObject; astore 2 // store scope in slot 2 aload 2 invokedynamic get:x(Object;)I // program point 1 istore 3 iload 3 aload 2 invokedynamic get:y(Object;)I // program point 2 invokedynamic imul(II)I // program point 3 ireturn  
  • 41. public static f(ScriptFunction;Object;)I aload 0 invokevirtual ScriptFunction.getScope()ScriptObject; astore 2 aload 2 invokedynamic get:x(Object;)I // program point 1 istore 3 iload 3 aload 2 invokedynamic get:y(Object;)I // program point 2 invokedynamic imul(II)I // program point 3 ireturn // catch (UnwarrantedOptimismException e) iconst_4 anewarray Object // 4 local variables in frame iload 3 // load variable 3 (tmp = x) invokedynamic populateArray([Object;I)[Object; goto rwe iconst_3 anewarray Object // 3 local variables in frame rwe: aload 0 // load function aload 1 // load ‘this’ aload 2 // load scope invokedynamic populateArray([Object;Object;Object;Object;)[Object; iconst_0 invokestatic getString$array(I)[String; invokestatic RewriteException.create(UnwarrantedOptimismException;[Object; [String;)RewriteException; athrow  
  • 42. GCD  –  Ideal   public static gcd(Object;II)I iload 1 istore 3 iload 2 istore 4 iload 3 iload 4 if_icmpeq L10 iload 3 iload 4 if_icmple L12 iload 3 iload 4 isub istore 3 goto L14 iload 4 iload 3 isub istore 4 goto L9 iload 3 ireturn
  • 43. GCD  –  vs  Nashorn   public static gcd(Object;II)I iload 1 istore 3 iload 2 istore 4 iload 3 iload 4 if_icmpeq L10 iload 3 iload 4 if_icmple L12 iload 3 iload 4 isub istore 3 goto L14 iload 4 iload 3 isub istore 4 goto L9 iload 3 ireturn public static gcd(Object;II)I try { iload 1 istore 3 iload 2 istore 4 iload 3 iload 4 if_icmpeq L10 iload 3 iload 4 if_icmple L12 iload 3 iload 4 invokedynamic isub(II)I //indy because sub may overflow istore 3 goto L14 iload 4 iload 3 invokedynamic isub(II)I //indy because sub may overflow istore 4 goto L9 iload 3 ireturn } catch (UnwarrantedOptimismException e) { //save state and throw RewriteException to linker }
  • 44. Sta*c  Compiler  Enhancements   •  Liveness   function liveness() { var x = 0; for (var i = 0;i < 10; i++) { x += i; } x += "test"; return x; } What  about  local  variables?  The  slot   type  is  hard  coded  in  the  local   variable  table!  
  • 45. Sta*c  Compiler  Enhancements   •  Liveness   function liveness() { var x = 0; for (var i = 0;i < 10; i++) { x += i; } x += "test"; return x; }  public static liveness(LObject;)LObject; iconst_0 invokestatic Integer.valueOf (I)Integer; astore 2 dconst_0 dstore 3 goto L2 aload 2 invokestatic JSType.toNumber (LObject;)D dload 3 dadd invokestatic Double.valueOf (D)Double; astore 2 dload 3 dconst_1 dadd dstore 3 dload 3 ldc 10.0 dcmpg iflt L3 aload 2 ldc "test" invokedynamic ADD:OOO_I(LObject;LObject;)Object astore 2 aload 2 areturn local x Ljava/lang/Object; L0 L6 2 local i D L0 L6 3
  • 46. Sta*c  Compiler  Enhancements   •  Liveness   function liveness() { var x = 0; for (var i = 0;i < 10; i++) { x += i; } x += "test"; return x; }   public static liveness(Object;)Object; iconst_0 istore 1 iconst_0 istore 3 iload 3 bipush 10 if_icmpge L10 iload 1 iload 3 invokedynamic iadd(II)I istore 1 iload 3 dup iconst_1 invokedynamic iadd(II)I istore 3 pop goto L9 iload 1 invokestatic Integer.valueOf(I)Integer; ldc "test" invokestatic ADD(Object;Object;)Object; astore 2 aload 2 areturn // exception handler goes here... local x L6 L13 1 I local x L13 L2 2 Object; local i L8 L2 3 I
  • 48. Field  Representa*on   •  jdk.nashorn.internal.runtime.ScriptObject –  Contains  a  PropertyMap •  Shape   –  Contains  a  number  of  fields   •  Scope  variables   –  Contains  a  growing  array   •  Spills  –  also  scope  variables   –  and  lots  of  other  things,  e.g.  ArrayData    
  • 49. Field  Representa*on   public abstract class ScriptObject implements PropertyAccess { protected Object[] spillObjects; long spillPrimitives; // most guards are a ref comparison on map private PropertyMap map; } public JO$4 extends ScriptObject { private Object o0, o1, o2, o3; long p1, p2, p3, p4; }                
  • 50. Property  Maps   PropertyMap AccessorProperty: red (flags = 0) slot = 0 AccessorProperty: green (flags = 0) slot = 1 AccessorProperty: blue (flags = 0) slot = 3 SpillProperty: timeStamp (flags = NON_MODIFIABLE), index = 0 •  Immutable   •  Copy  on  write  when  any  aspect   changes   •  Used  for  reference  guards  for  almost   all  invokedynamic  sites  
  • 51. Field  Representa*on   var scopeVar; function f() { scopeVar &= 17; }            
  • 52. Field  Representa*on   var scopeVar; function f() { scopeVar &= 17; }             1.  Load  scope  var  (getfield),  stored  as  Object,  is  a   java.lang.Integer 2.  Coerce  to  int  (unbox  from  java.lang.Integer)   3.  Execute  logical  and  (iand)   4.  Coerce  result  to  object  (box  to  java.lang.Integer)   5.  putfield  result  
  • 53. Field  Representa*on   var scopeVar; function f() { scopeVar &= 17; }             1.  Load  scope  var  (getfield),  stored  as   java.lang.Integer 2.  Coerce  to  int  (unbox  from  java.lang.Integer)   3.  Execute  logical  and     4.  Coerce  result  to  object  (box  to  java.lang.Integer)   5.  putfield  result  
  • 54. Field  Representa*on   public abstract class ScriptObject implements PropertyAccess { protected Object[] spillObjects; long spillPrimitives; // most guards are a ref comparison on map private PropertyMap map; } public JO$4 extends ScriptObject { private Object o0, o1, o2, o3; p4; }                
  • 55. Field  Representa*on   public abstract class ScriptObject implements PropertyAccess { protected Object[] spillObjects; protected long[] spillPrimitives; s // most guards are a ref comparison on map private PropertyMap map; } public JO$4 extends ScriptObject { private Object o0, o1, o2, o3; private long j0, j1, j2, j3;, p2, p3, p4; }
  • 56. Field  Representa*on   “EWW!  Fat  pointers”   public abstract class ScriptObject implements PropertyAccess { protected Object[] spillObjects; protected long[] spillPrimitives; s // most guards are a ref comparison on map private PropertyMap map; } public JO$4 extends ScriptObject { private Object o0, o1, o2, o3; private long j0, j1, j2, j3;, p2, p3, p4; }
  • 57. Field  Representa*on   obj.j = (long)x; //int obj.j = x; //long obj.j = Double.doubleToLongBits(x); //double obj.o = x; //object return (int)obj.j; //int return obj.j; //long return Double.longBitsToDouble(obj.j); //double return obj.o; //object SePers   GePers  
  • 58. Property  Maps  and  Types   •  Immutable   •  Copy  on  write  when  any  aspect  changes   •  Used  for  reference  guards  for  almost  all   invokedynamic  sites   PropertyMap AccessorProperty: red (flags = 0) slot = 0, type = int AccessorProperty: green (flags = 0) slot = 1, type = int AccessorProperty: blue (flags = 0) slot = 3, type = int SpillProperty: timeStamp (flags = NON_MODIFIABLE), index = 0, type = object
  • 59. Property  Maps  and  Types   PropertyMap AccessorProperty: red (flags = 0) type=int AccessorProperty: green (flags = 0) type=int AccessorProperty: blue (flags = 0) type=object SpillProperty: timeStamp (flags = NON_MODIFIABLE),type=object •  Immutable   •  Copy  on  write  when  any  aspect  changes   •  INCLUDING  FIELD  TYPE   •  Used  for  reference  guards  for  almost  all   invokedynamic  sites   •  INCLUDING  FIELD  GETTERS  AND  SETTERS   PropertyMap AccessorProperty: red (flags = 0) slot = 0, type = int AccessorProperty: green (flags = 0) slot = 1, type = int AccessorProperty: blue (flags = 0) slot = 3, type = int SpillProperty: timeStamp (flags = NON_MODIFIABLE), index = 0, type = object
  • 60. Field  Representa*on   var scopeVar; function f() { scopeVar &= 17; }             1.  Load  scope  var  (getfield),  stored  as   java.lang.Integer 2.  Coerce  to  int  (unbox  from  java.lang.Integer)   3.  Execute  logical  and  (iand)   4.  Coerce  result  to  object  (box  to  java.lang.Integer)   5.  putfield  result  
  • 61. Field  Representa*on   var scopeVar; function f() { scopeVar &= 17; }             1.  Load  scope  var  (getfield),  stored  as                  long 1.  Coerce  to  int  (l2i)   2.  Execute  logical  and  (iand)   3.  Coerce  to  long  (i2l)   4.  putfield  result  
  • 62. Field  Representa*on   •  BePer  representa*on?   – Unsafe?   – Needs  some  JVM  magic,  anyway   – Test  implementa*on:   sun.misc.TaggedArray – Object  shape  change  on  GC?   – Let’s  form  an  expert  group!        
  • 63. Closing  the  circle:      Op*mis*c  Buil*ns    
  • 64. Op*mis*c  buil*ns       /** * ECMA 15.4.4.7 Array.prototype.push (args...) * * @param self self reference * @param args arguments to push * @return array length after pushes */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object push(final Object self, final Object... args) { try { final ScriptObject sobj = (ScriptObject)self; if (bulkable(sobj) && sobj.getArray().length() + args.length <= JSType.MAX_UINT) { final ArrayData newData = sobj.getArray().push(true, args); sobj.setArray(newData); return newData.length(); } long len = JSType.toUint32(sobj.getLength()); for (final Object element : args) { sobj.set(len++, element, true); } sobj.set("length", len, true); return len; } catch (final ClassCastException | NullPointerException e) { throw typeError(Context.getGlobal(), e, "not.an.object", ScriptRuntime.safeToString(self)); } }    
  • 65. Relinking  Callsites   •  Can  now  be  done  with  Excep*ons  as  well  as  guards  or  SwitchPoints   •  For  example:  con*nuous  arrays   –  Previously  done  with  mul*ple  guards   •  array[x] & 17 •  Array  gePer  links  to:   try { //combinator – not real code return ((ContinuousArrayData)scriptObject. getArrayData()). getElementGetter(int.class). get(index); //turns AIOOBE to CCE } catch (ClassCastException e) { //relink } "  
  • 66. Op*mis*c  buil*ns       /** * ECMA 15.4.4.7 Array.prototype.push (args...) * * @param self self reference * @param args arguments to push * @return array length after pushes */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object push(final Object self, final Object... args) { try { final ScriptObject sobj = (ScriptObject)self; if (bulkable(sobj) && sobj.getArray().length() + args.length <= JSType.MAX_UINT) { final ArrayData newData = sobj.getArray().push(true, args); sobj.setArray(newData); return newData.length(); } long len = JSType.toUint32(sobj.getLength()); for (final Object element : args) { sobj.set(len++, element, true); } sobj.set("length", len, true); return len; } catch (final ClassCastException | NullPointerException e) { throw typeError(Context.getGlobal(), e, "not.an.object", ScriptRuntime.safeToString(self)); } }    
  • 67. Op*mis*c  buil*ns       // pre: linker checks that callsite argument matches @SpecializedFunction(guard=SpecializedFunction.Guard.CLASSCAST_EXCEPTION_CONTINUOUS_ARRAY) public static long push(final Object self, final int arg) { try { return ((ContinuousArrayData)self).getArray()).push(arg); } catch (final NullPointerException e) { //fallthru } throw new ClassCastException();  }
  • 68. Op*mis*c  buil*ns •  Lots  of  candidates   –  Array •  push, pop, shift, unshift, length –  String •  charAt, charCodeAt, length –  Number, Math –  Function.apply to    Function.call –  … •  We  can  use  the  same  recompila*on  framework   for  na*ve  methods  as  for  JavaScript  methods  
  • 69. An*paPern  that  JS  programmers  love   var Class = { create: function() { return function() { //vararg this.initialize.apply(this, arguments); } } }; Color = Class.create(); Color.prototype = { red: 0, green: 0, blue: 0, initialize: function(r, g, b) { this.red = r; this.green = g; this.blue = b; }, toString: function() { return this.red + “ “ + this.green + “ “ + this.blue; } } print(new Color(0xff, 0xee, 0xcc));
  • 71. Par*al  Evalua*on   for (var i = 0; i < x.length; i++) { //x is loop invariant ) •  x  can  use  MethodHandle.constant  as  an  indy   gePer.   •  We  can  use  a  SwitchPoint  to  invalidate  it,   given  that  x  is  modified  in  the  scope   •  Either  forbid  this  callsite  from  being  constant   again,  or  allow  n  retries   •  Or  try  with  a  receiver  guard  
  • 72. U*lize  java.nio.ByteBuffer •  Anyone  using  WebGL/ECMA  6  TypedArrays   can  get  near-­‐na*ve  performance   •  java.nio.ByteBuffer   •  5-­‐10x  microbenchmark  improvements   •  Exported  BufferArray  to  avatar.js  
  • 73. JVM  /  JDK  op*miza*ons   •  BePer  type  checking   •  Math  intrinsics   •  Inlining  modifica*on   •  Experiments  with  par*al  escape  analysis  /  boxing   removal   •  Uncommon  trap  placement   •  java.lang.invoke –  Had  to  significantly  beef  up   MethodHandles.catchException and  many  more •   …  
  • 74. There’s  SO  MUCH  MORE  I  WANT  TO   TELL  YOU  
  • 75. The  cost  of  all  this:  warmup  
  • 76. Warmup   •  The  need  to  recompile  methods  has  increased   warmup  *me   •  Tricks   – RewriteException  contains  scope   •  More  types  are  known  when  recompiling   – Heuris*cs   – Lazy  compila*on  
  • 77. function gcd(x, y) { var a = x; var b = y; while (a != b) { if (a > b) { a = a - b; } else { b = b - a; } } return a; } gcd(x, y); Compiles  gcd  
  • 78. function gcd(x, y) { var a = x; var b = y; while (a != b) { if (a > b) { a = a - b; } else { b = b - a; } } return a; } gcd(x, y); Compiles  gcd  
  • 79. function gcd(x, y) { var a = x; var b = y; while (a != b) { if (a > b) { a = a - b; } else { b = b - a; } } return a; } Does  not  compile  gcd  
  • 80. Lazy  Compila*on   •  Methods  are  only  compiled  on  demand   •  At  link  *me   – if  no  matching  signature  exists,  compile  one,  as   specific  as  possible   – If  matching  signature  does  exist,  try  to  compile  an   even  more  specific  one   •  Code  quality  is  the  same  as  eager  compila*on   – Scope  depths  are  maintained  
  • 81. Warmup   •  Tricks  (for  run  2)   – Persistent  code  cache  (--persistent-code- cache)   – Op*mis*c  type  informa*on  also  cached  to  disk   – TODO:  parsed  script  for  par*al  recompila*on   •  Reduces  the  second  run  to  a  very  fast  startup   – …  not  the  first  run,  however  
  • 83.    
  • 84. Profiling  and  Java  Flight  Recorder   •  A  JFR  “Nashorn”  buPon   •  JFR  event  produc*on  is  simple,  low  overhead,   and  doesn’t  require  closing  the  source  base   •  Unique  possibility  to  create  a  JavaScript   profiler  that  no  one  else  can  do  
  • 85. Profiling  and  Java  Flight  Recorder   •  A  Nashorn  JavaScript  method  is  bytecode   •  It  has  local  variable  tables,  names,  line   numbers   •  Fits  100%  into  the  JFR  framework  already   •  (IDE  plugin  for  source  level  mapping)   •  I  already  use  JFR  every  day  with  this  
  • 86. JFR  events  –  the  sky’s  the  limit   •  Megamorphic  callsite   •  Subop*mal  object  shape   •  Callsite  hits,  misses,  values   •  Scope  access   •  Fast  scope  access   •  with  entry/exit,  eval,  an*paPerns   •  Split  methods   •  Excep*ons   •  Relink  with  relink  reason   •  Assump*on  made   •  Assump*on  invalidated     •  Code  pipeline  reuse     •  Timing     •  Specialized  method  invoca*on     •  Type  widening   •  Method  invalida*on   •  Boxing  /  unboxing     •  Non-­‐trivial  callsites   •  Use  of  arguments     •  Use  of  callee   •  Code  spliung   •  Class  crea*on   •  Versions  of  compiled  func*ons     •  Code  cache  store/reuse     •  Array  meta  informa*on     •  Compila*on  *me     •  Slow  source  lines     •  Byte  code  size   •  IR  size  histograms     •  Index  access  on  non-­‐arrays   •  Non-­‐index  access  on  arrays   •  …  
  • 87. The  Future   •  Avatar   •  the  JVM     •  the  JDK     •  Nashorn     •  the  Hardware  (?)  
  • 88. 0   1   2   3   4   5   6   7   rhino   nashorn  jdk8   nashorn  jdk9  
  • 89. The  Future   Let  Nashorn  be  the  intelligent  dynamic  language   execu*on  framework  for  the  JVM,  regardless  of   frontend.  
  • 90. Q  &  A?   Give  us  your  benchmarks,  your  experiments,  your  hacks,     your  patch  sets,  we’d  love  your  help!  
  • 91. Extra  Slides  awer  this  point  
  • 92. Relinking  Callsites   •  An  indy  callsite  is  a  subclass  of   GuardedInvocation •  Invalida*on  mechanisms:   – Op*onal  guard   – Op*onal  SwitchPoint
  • 93. Relinking  Callsites   •  An  indy  callsite  is  a  subclass  of   GuardedInvocation •  Invalida*on  mechanisms:   – Op*onal  guard   – Op*onal  SwitchPoints  (0  …  n)   – Op*onal  Excep*on   •  Typically  ClassCastException
  • 94. /** * Constructor for a rewrite exception thrown from an optimistic function. * * @param e the {@link UnwarrantedOptimismException} that triggered this exception. * @param byteCodeSlots contents of local variable slots at the time of rewrite at the program point * @param byteCodeSymbolNames the names of the variables in the {@code byteCodeSlots} parameter. * * The array might have less elements, and some elements might be unnamed (the name can be null). The * information is provided in an effort to assist evaluation of expressions for their types by the * compiler doing the deoptimizing recompilation, * and can thus be incomplete - the more complete it is, the more expressions can be evaluated by the * compiler, and the more unnecessary deoptimizing compilations can be avoided. * * @return a new rewrite exception */ public static RewriteException create(final UnwarrantedOptimismException e, final Object[] byteCodeSlots, final String[] byteCodeSymbolNames); Linker  generates  “restOf”  method,  which  is  idenLcal  but  takes  only   RewriteExcepLon  as  argument,  rewrites  the  frame  state  and  jumps  to   the  corresponding  execuLon  point  unLl  “restOf”  method  has   executed.  Old  method  is  invalidated.  Next  call  will  generate  a  wider   version.  
  • 95. apply  to  call return function() { //vararg this.initialize.apply(this, arguments); } public static L:3(ScriptFunction;Object;[Object;)Object; aload 2 // args array aload 0 // callee iconst_0 // actual number of declared params invokestatic Global.allocateArguments([Object;Object;I)[Object; astore 3 aload 1 invokedynamic get:initialize(Object;)Object; dup invokedynamic get:apply(Object;)Object; swap aload 1 aload 3 invokedynamic dyn:call(Object;Object;Object;Object;)Object; pop getstatic ScriptRuntime.UNDEFINED areturn  
  • 96. return function() { //vararg this.initialize.apply(this, arguments); } public static L:3(ScriptFunction;Object;III)Object; aload 1 invokedynamic get:initialize(Object;)Object; dup invokedynamic get:apply(Object;)Object; //really loads “call” swap aload 1 iload 2 iload 3 iload 4 invokedynamic dyn:call(Object;Object;Object;III)Object; pop getstatic ScriptRuntime.UNDEFINED; areturn apply  to  call
  • 97. return function() { //vararg this.initialize.apply(this, arguments); } public static L:3(ScriptFunction;Object;III)Object; aload 1 invokedynamic get:initialize(Object;)Object; dup invokedynamic get:apply(Object;)Object; //really loads “call” swap aload 1 iload 2 iload 3 iload 4 invokedynamic dyn:call(Object;Object;Object;III)Object; pop getstatic ScriptRuntime.UNDEFINED; areturn apply  to  call local :callee L0 L1 0 ScriptFunction; local :this L0 L1 1 Object; local :xarg0 L0 L1 2 I local :xarg1 L0 L1 3 I local :xarg2 L0 L1 4 I
  • 98. Function.prototype.call = function() { throw “This is a JavaScript! No performance for you!”; } SwitchPoint  based  dynamic  invalida*on  –  same  mechanism  as  everewhere  else   apply  to  call