Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Future Java: Project Valhalla LW2

Future Java: Project Valhalla LW2

A quick look at major changes with the latest build of Project Valhalla.
A workshop with London Java Community

Uberto Barbini

November 04, 2019
Tweet

More Decks by Uberto Barbini

Other Decks in Programming

Transcript

  1. Valhalla Project Valhalla Started 2014 JEP 169: Value Objects JEP

    218: Generics over Primitive Types Uberto Barbini @ramtop
  2. pe Value Types Inline Classes Inline Types “Codes like a

    Class works like an int” Reference Immutability Non Nullable Primitive Generics
  3. Which Field Descriptor? B byte signed byte C char Unicode

    character code point in the Basic Multilingual Plane, encoded with UTF-16 D double double-precision floating-point value F float single-precision floating-point value I int integer J long long integer L ClassName reference an instance of class ClassName Q ClassName inline types S short signed short Z boolean true or false [ reference one array dimension
  4. e Q-Types in L-World For any given named class or

    interface Foo we say that L-Foo is the L- type of Foo. When the type is obviously not a value type we may omit the “L-” prefix, thus Object and Object[] for L-Object and L-Object[]. As dictated by today’s JVMS, any variable of L-type will accept null. A Q-type is a reference to a value instance. All value instances have a named class, which is incorporated into the spelling of the Q-type. (For regularity we say “reference to a value”, but the reference is not detectable to the user; there are no identity or aliasing relations between values.) For any given named value class Val we say that Q-Val is the Q-type of Val. http://cr.openjdk.java.net/~jrose/values/q-types.html September 2018
  5. LW2 These builds have many limitations: No support for atomic

    fields containing value types. No support for @Contended value type fields. No JVMTI, AOT, CDS, ZGC, or serviceability agent. Only -Xint and C2 are supported. No C1, no tiered compilation, and no Graal. The interpreter is not optimized, since our focus is on the JIT implementation. Unsafe field and array-accessor APIs are not supported for value types. Low-level unsafe APIs are UNSAFE and will not be changed to support value types. If a value type has been flattened in a container, unsafe does not know the layout, so getObject could return the first flattened element rather than the expected reference. Immutable types can be copied, so updates may not be seen.
  6. pe Constructors final value class Point { public final int

    x; public final int y; public Point(int x, int y) { this.x = x; this.y = y; } public static Point of(int x, int y) { Point p = Point.default; Point p1 = __WithField(p.x, x); //WithField operator is allowed only with -XDallowWithFieldOperator Point p2 = __WithField(p1.y, y); return p2; }
  7. Can Implement Interfaces public value class Dog implements Animal {

    public final String name; public Dog(String name) { this.name = name; } @Override public String name() { return name; } @Override public String sound() { return "woof"; } }
  8. No Inheritance public class Alsatian implements Animal { //Ok public

    class Alsatian extends Dog { // Error: cannot inherit from final com.gamasoft.animals.Dog public value class Alsatian extends Dog { // Error: value type may not extend another value or class
  9. toString() public value class Cat implements Animal { public final

    String name; public Cat(String name) { this.name = name; } @Override public String name() { // return super.toString(); //Error: value types do not support invocation of super.toString return name; }
  10. Equals == var p1 = new Point(3, 4); var p2

    = new Point(4, 5); var p3 = p1.displace(1,1); assertEquals(p2, p3); assertTrue(p2 == p3); //Inline Types do support == as byte for byte comparison
  11. Arrays var memBefore = Runtime.getRuntime().freeMemory(); Point[] values = new Point[1_000_000];

    var memUsed = memBefore - Runtime.getRuntime().freeMemory(); System.out.println("Memory for 1M Points " + memUsed); //8MB System.out.println("Point default " + values[0]); //default
  12. Nullability var list = new ArrayList<Point>(); list.add(Point.of(3, 4)); list.add(null); //compile

    error: incompatible types: <null> cannot be converted to Point assertEquals(1, list.size()); assertEquals(new Point(3, 4), list.get(0));
  13. Nullable ? Types var list = new ArrayList<Point?>(); list.add(Point.of(3, 4));

    list.add(null); //ok now with ? wrapper assertEquals(2, list.size()); assertEquals(new Point(3, 4), list.get(0)); assertEquals(null, list.get(1));
  14. Generics var d = new Dog("Lassie"); //VT var c =

    new Cat("Ginger"); //VT var s = new Shark(); //Object List<Animal> animalList = new ArrayList<>(); animalList.add(d); animalList.add(c); animalList.add(s); Set<Cat> catSet = new HashSet<>(); catSet.add(new Cat("Tom")); catSet.add(new Cat("Jerry")); catSet.add(new Cat("Silvester"));
  15. Flattenable public value class Line { public __Flattenable final Point

    startPoint; public __Flattenable final Point endPoint; public Line(Point p1, Point p2) { this.startPoint = p1; this.endPoint = p2; } } var memBefore = Runtime.getRuntime().freeMemory(); var values = new Line[1_000_000]; var memUsed = memBefore - Runtime.getRuntime().freeMemory(); System.out.println("Memory for 1M Lines " + memUsed); //16MB