– 64 bits (for hotspot) wasted for every objects Arrays of objects are array of references – Cache misses :( Too many references – Too much allocation → Slow the GC
for that ! Specialization of the generic code at runtime ? By the JIT ! Generics over objects still erased for compatibility Wildcards / Boxing List<?> vs List<int> vs List<Integer>
auto- vectorisation of loop over arrays of primitives Add API to access to SIMD/AVX ops – Need to define 128/256/512 bits int/double ? • Use value types (defined by the JDK) – Intrinsics for the VM
SIMD/AVX – stealth valhalla: Value types in the VM let JRuby, Groovy, Scala, etc play with it first Java 11 – full valhalla: Value types + Specialized Generics
list = new ArrayList<String>(); use super type: var anonymous = new Object() { int x; }; not supported: var lambda = x -> x + 2; var ref = String::length;
... map.computeIfAbsent(key, _ - > new HashSet<>()) .add(value); Lambda parameters open a new scope map.merge(key, value, (old, value) - > old + value); Better inference – Fix cases where overloading is obvious for a human
to represent ‘dumb’ data – Abstraction ‘it’s a data class’ – Less boiler plate Generate (at runtime ?) – equals, hashCode, toString, getters ? – Value types also need that too !
! public Expr simplify(Expr expr) { return switch(expr) { case Add(Value(v1), Value(v2)) -> new Value(v1 + v2)) case Add(e1, e2) -> simplify(...) case Value _ -> expr }; } Use of local variable (non final)
/ Action • A text transformed as an automata at runtime • Action: a static method to call if the pattern match No instanceof guardWithTest is a typecheck on runtime classes
types, use the double switch trick ! String s; int index = invokedynamic(expr); recipe […] switch(index) { case 0: s = "JSObject"; break; case 1: s = "JSArray"; break; default: s = "other"; } return s;
may match the same pattern switch(expr) { case IAdd(IValue(v1), IValue(v2)) -> ... case IAdd(e1, e2) - > ... IAdd IValue IValue extract expr v1 v2 action1 action2
... case IAdd(e1, e2) - > … At Runtime, we construct Add extract Add v1 action2 Value v1 action1 Value v2 After N guards, use java.lang.ClassValue instead
are objects) /* data */ class Add { private final Expr left; private final Expr right; ... public Optional<Tuple<Expr, Expr>> unapply() { return Some((left, right)); } } Extract the values => 2 object creations
the help of the VM Reify the stackframe as an object var frame = StackFrame.alloc(LExpr;LExpr;II) add.deconstructor(frame.refAt(0), frame.refAt(1)); … action.invokeWithStackFrame(frame, 2); John Rose starts a prototype :)