Java VMの改善案が楽しそう

なんか、Java VMの改善案がでてますね。
すげー楽しそうです。
http://cr.openjdk.java.net/~jrose/pres/201407-JVMEvolution.pdf


プロジェクトValhallaとプロジェクトPanamaがあります。
http://openjdk.java.net/projects/valhalla/
http://openjdk.java.net/projects/panama/


Valhallaは、Value TypesとSpecialization、PanamaはArrays 2.0とLayoutsがあります。
概要をまとめてみますが、かなり適当な解釈で書いてたりするので、細かいことはちゃんと原文みてください。

Value Types

簡単にいえば、新しい基本型を定義できるようにするというものです。
http://cr.openjdk.java.net/~jrose/values/values-0.html

__ByVal class Point{
  final int x;
  final int y;
}

のように、クラス定義のときになんらか指定しておくと、参照を経由せずに値を保持・受け渡しができる型になるという感じです。文法に関しては今きめることじゃないから気にするなと。


もちろん、nullをもつことはできません。
実用としては、たとえば128ビット整数だとか、unsigned型だとか。
あと、タプルに関しての言及もありました。
最適化が進んだとはいえ、なんだかんだでオブジェクトというのは基本型よりもパフォーマンスが悪いので、たとえばOptionalも、コードの健全性はあがるんですけど、パフォーマンスが気になるところでは使いづらいということがあります。でも、基本型と同等の扱いになれば、パフォーマンスの問題は気にする必要がなくなります。また、Optionalが基本型相当の扱いになると、Optional型の変数自体がnullになるという危険性もなくなって、nullとの無縁度があがっていいですね。

Specialization

特殊化、ですね。
http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html


簡単にいうと、Genericsで、C++のテンプレートのようにそれぞれの型に対応した実装を生成してしまおうってことです。
どのような場合に、というと、つまり基本型です。

List values = new ArrayList();

のようなことが書けるようにして、そのときint用の特別なArrayListの実装を生成してしまうということです。
もちろん、上記にあげたValue Typesにも対応します。


そうすると、パフォーマンスを考慮して汎用クラスと基本型専用のクラスをわけるというようなことが不用になるわけです。StreamとIntStreamのような。


たとえば次のようなGenericなクラスがあるとします。

class Box{
  T value;
  Box(T v){
    value = v;
  }
  T getValue(){
    return T;
  }
}


これ、実際にはこんなクラスとしてコンパイルされてたわけですね。

class Box{
  Object value;
  Box(Object v){
    value = v;
  }
  Object getValue(){
    return value;
  }
}


これを、こんな感じでコンパイルするようにします。

class Box{
  Object*T value;
  Box(Object*T v){
    value = v;
  }
  Object*T getValue(){
    return value;
  }
}


で、参照型のときはそのままObjectを扱う実装を使うんですが、T=intだと

class Box{t=int}{
  int value;
  Box(int v){
    value = v;
  }
  int getValue(){
    return value;
  }
}

という型にするという。


ようするに、

Box box = new Box();

というのは

Box{t=int} box = new Box{t=int}();

となるということです。


ここで、キャストの問題があります。
Box型はgetValueメソッドがObjectを返すので、BoxやBoxへのダウンキャストが可能です。けど、Box{t=int}型はBox型との互換性はありません。
なので、

Box box = new Box();
List nums = new List();

ということはできなくなるようです。


あと面白いのが型ごとのメソッドが定義できるという話。

class Box{
  T value;
   int getTwice(){
    return value * 2;
  }
}

のようにすると、T=intのときだけ有効になるメソッドが定義できると。


特殊化の問題点としてはオーバーロードの問題があって、Genericなクラスにはパラメータの型と基本型の互換性がないことを前提にしたオーバーロードがあったりして、そこでメソッド解決できないことができてきます。

List{
  void remove(T o);
  void remove(int idx);
}

というのは今はあまり問題ないですが、T=intができるようにすると問題があります。


あとはnullの問題。

Map{
  U get(T key);
}

というメソッドで該当する値がないときにnullを返しますが、U=intのときどうするんだ、と。
intの場合0のようなデフォルト値を返すというのもありですが、そうすると値がないときとの差がわかんない。
ただ、これは例えばMapの場合だと、キーにnullという値が割り当てられてることとなにも値が割り当てられてない場合とが現状でも判別できてないんで、いいんじゃね?という話もあったりするようです。


IntStreamとは何だったのか、と早く言いたいw

Array 2.0

文字通り、配列の拡張です。
いまの配列は一次元だけだったり、要素の変更が防げなかったりするのですが、ニ次元の配列やread-onlyな配列が定義できるようにということのようです。
いままで二次元の配列は、一次元の配列を扱う一次元の配列で表現していました。これをCの配列のように、連続した空間を分割する形での二次元配列が実現できるようにするということです。
read-only配列は、並行処理に必要ということです。

Layouts

クラスのフィールドの配置を決めれるようにするということです。
そうすると、ネイティブコードとのやりとりがやりやすくなります。
あと、ネットワークやストレージでも、何も考えずに値をやりとりできるようになって便利です。

まとめ

全般にハードウェアにあわせたコードがかけるようにして低レイヤーのパフォーマンスを向上するという感じですね。
Javaの性格が根底から変わる感じです。
実際に使えるのがいつになるかわかりませんが、方向性が見えて楽しみです。