関ジャバ 20130731 invokedynamic

72
関西Javaエンジニアの会 JVMでの動的言語サポート フリュー株式会社 @jyukutyo 阪田 浩一 #kanjava 1 1 13822日木曜日

Upload: jyukutyo

Post on 24-May-2015

139 views

Category:

Technology


7 download

DESCRIPTION

20130731に関ジャバで発表したinvokedynamicのスライドです。

TRANSCRIPT

Page 1: 関ジャバ 20130731 invokedynamic

関西Javaエンジニアの会JVMでの動的言語サポート

フリュー株式会社@jyukutyo

阪田 浩一#kanjava

1

113年8月22日木曜日

Page 2: 関ジャバ 20130731 invokedynamic

@jyukutyo

著書 3冊

関西Javaエンジニアの会(関ジャバ) 発起人・運営

Fight the Futurehttp://jyukutyo.hatenablog.com/

フリュー株式会社 所属プリ機と連携する

画像SNS「ピクトリンク」開発・運用に従事.会員数500万人!

Scalaカンファレンススポンサー企業!

エンジニア歴10年 34歳SI業界での客先常駐 9年Web系? 1年強

デブサミ関西2012 スピーカー

文学部哲学科卒

2

塾講師アルバイト

213年8月22日木曜日

Page 3: 関ジャバ 20130731 invokedynamic

JVMはいまや多言語プラットフォーム

3

313年8月22日木曜日

Page 4: 関ジャバ 20130731 invokedynamic

4

Java Virtual Machine

Java Groovy Scala JRuby

413年8月22日木曜日

Page 5: 関ジャバ 20130731 invokedynamic

JVMはJava言語仕様をまったく理解していない

5

513年8月22日木曜日

Page 6: 関ジャバ 20130731 invokedynamic

classファイル形式のバイナリのみ理解する

6

613年8月22日木曜日

Page 7: 関ジャバ 20130731 invokedynamic

つまり

7

713年8月22日木曜日

Page 8: 関ジャバ 20130731 invokedynamic

仕様を満たしたclassファイルだったら

なんでもいい

8

813年8月22日木曜日

Page 9: 関ジャバ 20130731 invokedynamic

とはいうものの

9

913年8月22日木曜日

Page 10: 関ジャバ 20130731 invokedynamic

JVMは静的型付け言語である

Java向けに作成されている

10

1013年8月22日木曜日

Page 11: 関ジャバ 20130731 invokedynamic

それはJVMのメソッド呼び出し命令

に現れている

11

1113年8月22日木曜日

Page 12: 関ジャバ 20130731 invokedynamic

Java6までのJVMのメソッド呼び出し命令

12

命令 説明

invokestatic staticメソッドを呼び出し

invokespecialコンストラクタ、

privateなインスタンスメソッド、superクラスのメソッドの呼び出し

invokevirtualprivate以外のインスタンスメソッドの

呼び出し

invokeinterfaceレシーバの型がインタフェースであるインスタンスメソッドの呼び出し

1213年8月22日木曜日

Page 13: 関ジャバ 20130731 invokedynamic

これでわかること

13

1313年8月22日木曜日

Page 14: 関ジャバ 20130731 invokedynamic

レシーバの型がわかる前提での命令しかない

14

1413年8月22日木曜日

Page 15: 関ジャバ 20130731 invokedynamic

かたや動的言語たち…

15

1513年8月22日木曜日

Page 16: 関ジャバ 20130731 invokedynamic

モンキーパッチあり〼

16

1613年8月22日木曜日

Page 17: 関ジャバ 20130731 invokedynamic

既存のクラスにフィールドやメソッドを追加したり削除したり

17

1713年8月22日木曜日

Page 18: 関ジャバ 20130731 invokedynamic

Java6までは動的言語の側で

こうしたことを実現する実装をしていました

18

1813年8月22日木曜日

Page 19: 関ジャバ 20130731 invokedynamic

リフレクションとか動的プロキシとか

19

1913年8月22日木曜日

Page 20: 関ジャバ 20130731 invokedynamic

まあパフォーマンス悪くなりますよね

20

2013年8月22日木曜日

Page 21: 関ジャバ 20130731 invokedynamic

しかもJITコンパイル適用できないし

21

2113年8月22日木曜日

Page 22: 関ジャバ 20130731 invokedynamic

そこでJava7から!invokedyanmicの

登場ですよ

22

2213年8月22日木曜日

Page 23: 関ジャバ 20130731 invokedynamic

JSR 292: Supporting Dynamically

Typed Languages on the Java Platform

23

2313年8月22日木曜日

Page 24: 関ジャバ 20130731 invokedynamic

簡単に言うと、呼び出し対象の解決を実行時まで遅らせる

仕組みです

24

2413年8月22日木曜日

Page 25: 関ジャバ 20130731 invokedynamic

カスタムリンケージを定義できる、

とか言うみたいです

25

2513年8月22日木曜日

Page 26: 関ジャバ 20130731 invokedynamic

JVMにおける5つ目の

メソッド呼び出し命令です

26

2613年8月22日木曜日

Page 27: 関ジャバ 20130731 invokedynamic

JVMに導入することでJITコンパイルの恩恵も受けられる

27

2713年8月22日木曜日

Page 28: 関ジャバ 20130731 invokedynamic

実現したいこと:Cにある関数ポインタ的な

ものを使い、これが指す処理を呼び出す

仕組み28

2813年8月22日木曜日

Page 29: 関ジャバ 20130731 invokedynamic

(僕はCに詳しくないのでイメージでの理解です)

29

2913年8月22日木曜日

Page 30: 関ジャバ 20130731 invokedynamic

その関数ポインタ的なものが

MethodHandle(以下MH)です

30

3013年8月22日木曜日

Page 31: 関ジャバ 20130731 invokedynamic

MHは実際に呼び出す処理と結びついています

31

3113年8月22日木曜日

Page 32: 関ジャバ 20130731 invokedynamic

32

対象の処理MH

3213年8月22日木曜日

Page 33: 関ジャバ 20130731 invokedynamic

動的言語のプログラミングで処理が変更されたら、

別のMHを生成するわけです

33

3313年8月22日木曜日

Page 34: 関ジャバ 20130731 invokedynamic

34

対象の処理MH

別の処理

新しいMH

3413年8月22日木曜日

Page 35: 関ジャバ 20130731 invokedynamic

MHはただの関数ポインタなので、

35

3513年8月22日木曜日

Page 36: 関ジャバ 20130731 invokedynamic

どういうコンテキストでMHが作られたか

別のオブジェクトが把握します

36

3613年8月22日木曜日

Page 37: 関ジャバ 20130731 invokedynamic

それがCallSite

37

3713年8月22日木曜日

Page 38: 関ジャバ 20130731 invokedynamic

CallSiteはMHを保持し、呼び出し元の

コンテキストを表すオブジェクト

38

3813年8月22日木曜日

Page 39: 関ジャバ 20130731 invokedynamic

39

対象の処理MH

CallSite

3913年8月22日木曜日

Page 40: 関ジャバ 20130731 invokedynamic

invokedynamic命令はCallSiteを取得して、MHを通して処理を

呼び出す

40

4013年8月22日木曜日

Page 41: 関ジャバ 20130731 invokedynamic

ではどうやってCallSiteを取得するのか?

41

4113年8月22日木曜日

Page 42: 関ジャバ 20130731 invokedynamic

それがbootstrapメソッド

42

4213年8月22日木曜日

Page 43: 関ジャバ 20130731 invokedynamic

CallSiteオブジェクトを返すstaticメソッド

43

4313年8月22日木曜日

Page 44: 関ジャバ 20130731 invokedynamic

各invokedynamic命令が最初に実行されるときに必ずbootstrapメソッドが

呼び出される仕組み

44

4413年8月22日木曜日

Page 45: 関ジャバ 20130731 invokedynamic

bootstrapメソッドがCallSiteオブジェクトを

返し…

45

4513年8月22日木曜日

Page 46: 関ジャバ 20130731 invokedynamic

invokedynamic命令とCallSiteオブジェクトが

関連づけられる

46

4613年8月22日木曜日

Page 47: 関ジャバ 20130731 invokedynamic

47

対象の処理MH

CallSite

bootstrap 生成

invokedynamic初回実行時に呼び出し

MHを保持する

関連づく

4713年8月22日木曜日

Page 48: 関ジャバ 20130731 invokedynamic

用語のまとめ

48

命令 説明

bootstrapメソッド

invokedynamicが最初に実行されるとき、JVMから呼び出されるstaticメソッド。戻り値はCallSiteオブジェクト。

CallSite呼び出し元を表すオブジェクト。MethodHandleを保持する。

MethodHandleある処理をポイントするオブジェクト。これを使ってその処理を呼び出せる。

4813年8月22日木曜日

Page 49: 関ジャバ 20130731 invokedynamic

これらのオブジェクトはAPIとして提供されている

49

4913年8月22日木曜日

Page 50: 関ジャバ 20130731 invokedynamic

java.lang.invokeパッケージ

50

5013年8月22日木曜日

Page 51: 関ジャバ 20130731 invokedynamic

たとえばMHを生成するには…

51

5113年8月22日木曜日

Page 52: 関ジャバ 20130731 invokedynamic

52

Lookup lookup = MethodHandles.lookup();

MethodHandle mh = lookup.findVirtual( String.class, "startsWith", MethodType.methodType( boolean.class, String.class ) );

MHの生成

5213年8月22日木曜日

Page 53: 関ジャバ 20130731 invokedynamic

MHの生成メソッド(いくつか)

53

メソッド 説明

Lookup#findVirtualインスタンスメソッドを呼び出す

MHを返す

Lookup#findConstructorコンストラクタを呼び出す

MHを返す

Lookup#findSetterフィールドへ書き込む

MHを返す

MethodHandles.constantつねに定数を返すMHを返す

5313年8月22日木曜日

Page 54: 関ジャバ 20130731 invokedynamic

CallSiteを生成するには…

54

5413年8月22日木曜日

Page 55: 関ジャバ 20130731 invokedynamic

55

CallSite cs = new ConstantCallSite(methodHandle);

CallSiteの生成

5513年8月22日木曜日

Page 56: 関ジャバ 20130731 invokedynamic

CallSiteの具象クラス

56

クラス 説明

ConstantCallSite MHを変更できない

MutableCallSite MHを変更できる

VolatileCallSiteMHを変更でき、

かつすべてのスレッドに即時反映される

5613年8月22日木曜日

Page 57: 関ジャバ 20130731 invokedynamic

bootstrapメソッドではこれらを使って

CallSiteを生成すればよい

57

5713年8月22日木曜日

Page 58: 関ジャバ 20130731 invokedynamic

僕が今わからないこと:JVM命令inovkedynamicが

bootstrapメソッドを見つけて呼び出す部分

58

5813年8月22日木曜日

Page 59: 関ジャバ 20130731 invokedynamic

Java 8からJavaでもindyが

使われるようになった!

59

5913年8月22日木曜日

Page 60: 関ジャバ 20130731 invokedynamic

ラムダ式

60

6013年8月22日木曜日

Page 61: 関ジャバ 20130731 invokedynamic

昔は匿名クラスにコンパイルされていた

けど…

61

6113年8月22日木曜日

Page 62: 関ジャバ 20130731 invokedynamic

(なのでラムダ式は匿名クラスの

シンタックスシュガーではないのです)

62

6213年8月22日木曜日

Page 63: 関ジャバ 20130731 invokedynamic

ラムダのクラスを実行時に生成する。

そしてインスタンス化するMHを生成する。

63

6313年8月22日木曜日

Page 64: 関ジャバ 20130731 invokedynamic

サンプル実行

64

6413年8月22日木曜日

Page 65: 関ジャバ 20130731 invokedynamic

なぜラムダ式でindyを使うのか

65

6513年8月22日木曜日

Page 66: 関ジャバ 20130731 invokedynamic

66

クラスファイルを少なくするため

インスタンスの生成方法をJVMが選択できるようにして、最適化するため

6613年8月22日木曜日

Page 67: 関ジャバ 20130731 invokedynamic

たとえば引数の値しか使わない処理の場合は、シングルトンインスタンスを戻すMHを生成する

ようにする67

6713年8月22日木曜日

Page 68: 関ジャバ 20130731 invokedynamic

indy自体は言語やミドルウェアを実装する人にとって

便利な機能

68

6813年8月22日木曜日

Page 69: 関ジャバ 20130731 invokedynamic

JooFluxという研究プロダクトでは、

indyを使って動的なアスペクト志向?を実現しているらしい

69

6913年8月22日木曜日

Page 70: 関ジャバ 20130731 invokedynamic

70

Java 7 invokedynamic の概要

http://www.slideshare.net/miyakawataku/java-7-invokedynamic-in-a-nutshell

めっちゃ勉強させてもらったサイトのご紹介

7013年8月22日木曜日

Page 71: 関ジャバ 20130731 invokedynamic

ご清聴ありがとう

ございました!

71

7113年8月22日木曜日

Page 72: 関ジャバ 20130731 invokedynamic

72

ここからはじめる、JSR-356 WebSocket

エスケイプ・フロム・レガシーJ2EE

Java プラットフォームにおける Batch アプリケーション (JSR 352)

エンタープライズ環境における並列処理の実装方法について

7213年8月22日木曜日