Kink: invokedynamic on a prototype-based language

965 views
883 views

Published on

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
965
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Kink: invokedynamic on a prototype-based language

  1. 1. Kink: プロトタイプベース言語での invokedynamic (構想)@miyakawa_taku2012-02-22JJUG Night Seminar
  2. 2. 1要旨• Kink という JVM 言語を作っています• JavaScript や Lua と同様に、クラスのないオブ ジェクト指向言語です• invokedynamic がどこに使えるものか考えて みました
  3. 3. 2論点• Kink の紹介 – クラスのない世界 – なんでもメソッド – 気になる性能は?• invokedynamic の使い所 – スロットアクセスの最適化 – SwitchPoint で実行モード切り替え
  4. 4. 3論点• Kink の紹介 – クラスのない世界 – なんでもメソッド – 気になる性能は?• invokedynamic の使い所 – スロットアクセスの最適化 – SwitchPoint で実行モード切り替え
  5. 5. 4クラスのない世界• クラスはなく値だけがある• データもメソッドもいきなり値のスロット (≒フィールド) に突っ込む &DOG = value DOG.&bark = { Bow! } printline(DOG.bark) # => Bow!
  6. 6. 5クラスのかわりに親• 自分自身がスロットを持っていなかったら親 から取ってくる• 親のことをプロトタイプとも言う &PROTODOG = value(bark : { Bow! }) &DOG = PROTODOG.child printline(DOG.bark) # => Bow!
  7. 7. 6親/子関係の一つ覚え• つまり子は親の名前空間を継承する• 様々な仕組みを親/子関係で実現する – クラス / インスタンス (のようなもの) – 親クラス / 子クラス (のようなもの) – 外側のスコープ / 内側のスコープ
  8. 8. 7なんでもメソッド• 足し算も掛け算もメソッド• 条件分岐もメソッド• 代入もメソッド• 引数渡しもメソッド
  9. 9. 8足し算も掛け算もメソッド• 演算子はメソッドの構文糖 (TOP + BOTTOM) * HEIGHT TOP.plus(BOTTOM).multiply(HEIGHT)
  10. 10. 9条件分岐もメソッド• if-then-else は bool 値のメソッド (N % 2 == 0).then { even } { odd } (N % 2 == 0).then({ even } { odd })
  11. 11. 10代入もメソッド• スロットへの代入はスロットのメソッド &NUM = 42 &NUM.assign(42)
  12. 12. 11引数渡しもメソッド• 引数渡しは仮引数列 (スロットのリスト) のメ ソッド &diff = { (&X &Y) X - Y } &diff = { [&X &Y] = _args X - Y }
  13. 13. 12気になる性能は?• tarai(13 6 0) (たらい回し関数、竹内関数) で マイクロベンチマーク &tarai = { (&X &Y &Z) (X <= Y).then { Y }{ tarai(tarai(X - 1 Y Z) tarai(Y - 1 Z X) tarai(Z - 1 X Y)) } } printline(tarai(~ argv.map { __.int }))
  14. 14. 13結果: bc よりは速いGNU bc 1.06.95Kink 2012-02-19 C Ruby 1.8.7 scm 5e5 Python 2.6.6 mawk 1.3.3 C Ruby 1.9.2 Lua 5.0.3 Groovy 1.7.0 JRuby 1.6.6 0 20 40 60 80 100 120 140 160 秒
  15. 15. 14つまりこんな言語• クラスがなくて値だけがある• 代入も制御構造もメソッド呼び出し• 速くするのはかなり難渋する• あと、末尾呼び出しでスタックオーバーフロー が起きないことを保証しています
  16. 16. 15論点• Kink の紹介 – クラスのない世界 – なんでもメソッド – 気になる性能は?• invokedynamic の使い所 – スロットアクセスの最適化 – SwitchPoint で実行モード切り替え
  17. 17. 16処理系の作り• プログラムはJVM バイトコードにせず、「評価 器」を作って実行する (cf. SICP 4章) call call&loop.do { print("twift!") slot proc slot proc loop} chunk chunk プログラム 抽象構文木 評価器
  18. 18. 17invokedynamic の使い所• そもそもJVM バイトコードにしないので、メソッ ド呼び出しがいきなり invokedynamic になるこ とはない• ただし、高速化のためにバイトコード生成を 使っている所はあって、そこに invokedynamic が使えるかも
  19. 19. 18スロットアクセスの最適化• スロットアクセスを速くするため、スロット集合 のクラスを実行時に生成している• 本来はアクセス元のコードでキャッシュを効か せて速くする (現在は未実装)• ここに invokedynamic が使えそう DOG DOG.bark bark { "Bow!" } jump { "Pong!" } ここに使う
  20. 20. 19スロットアクセスの最適化• キャッシュヒット → フィールドを直接取得• キャッシュミス → フォールバック• MethodHandles#guardWithTest が使えそう if (slots.getClass() == #cachedClass) { test return ((#cachedClass) slots).bar; target } else { deoptimize(); fallback return slots.get("bar"); }
  21. 21. 20SwitchPoint で実行モード切り替え• スロットやリストへの代入はメソッド呼び出し• 毎回メソッドを呼ぶと大変なコストなので、可 能な限りショートカット処理している• ここで SwitchPoint#guardWithTest が使えそう if 代入メソッドは再定義されていない? ショートカット処理 else 真面目にメソッド呼び出し
  22. 22. 21SwitchPoint で実行モード切り替え• SwitchPoint は MethodHandle のファクトリ – SP.guardWithTest(target, fallback):MethodHandle – 通常は target が実行される – SwitchPoint が invalidate されると、それ以降は fallback が実行される• 処理の実行モードを切り替えるのに使える – 代入処理の MH を SwitchPoint で生成 – 代入メソッドが再定義されたら invalidate
  23. 23. 22invokedynamic の使い所 (rep)• クラスのない言語でも充分使い所はある – スロットアクセスの最適化 – 実行モード切り替え
  24. 24. 23参考• Kink Programming Language – http://code.google.com/p/kink-lang/• V8 JavaScript Engine – http://code.google.com/p/v8/ – スロットアクセスを最適化する仕組みのパクリ元 (Hidden Class)• An efficient implementation of SELF – http://dl.acm.org/citation.cfm?id=74884

×