関ジャバ 20130731 invokedynamic

Post on 24-May-2015

142 views 7 download

description

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

Transcript of 関ジャバ 20130731 invokedynamic

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

フリュー株式会社@jyukutyo

阪田 浩一#kanjava

1

113年8月22日木曜日

@jyukutyo

著書 3冊

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

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

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

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

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

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

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

文学部哲学科卒

2

塾講師アルバイト

213年8月22日木曜日

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

3

313年8月22日木曜日

4

Java Virtual Machine

Java Groovy Scala JRuby

413年8月22日木曜日

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

5

513年8月22日木曜日

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

6

613年8月22日木曜日

つまり

7

713年8月22日木曜日

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

なんでもいい

8

813年8月22日木曜日

とはいうものの

9

913年8月22日木曜日

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

Java向けに作成されている

10

1013年8月22日木曜日

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

に現れている

11

1113年8月22日木曜日

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

12

命令 説明

invokestatic staticメソッドを呼び出し

invokespecialコンストラクタ、

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

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

呼び出し

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

1213年8月22日木曜日

これでわかること

13

1313年8月22日木曜日

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

14

1413年8月22日木曜日

かたや動的言語たち…

15

1513年8月22日木曜日

モンキーパッチあり〼

16

1613年8月22日木曜日

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

17

1713年8月22日木曜日

Java6までは動的言語の側で

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

18

1813年8月22日木曜日

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

19

1913年8月22日木曜日

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

20

2013年8月22日木曜日

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

21

2113年8月22日木曜日

そこでJava7から!invokedyanmicの

登場ですよ

22

2213年8月22日木曜日

JSR 292: Supporting Dynamically

Typed Languages on the Java Platform

23

2313年8月22日木曜日

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

仕組みです

24

2413年8月22日木曜日

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

とか言うみたいです

25

2513年8月22日木曜日

JVMにおける5つ目の

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

26

2613年8月22日木曜日

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

27

2713年8月22日木曜日

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

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

仕組み28

2813年8月22日木曜日

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

29

2913年8月22日木曜日

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

MethodHandle(以下MH)です

30

3013年8月22日木曜日

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

31

3113年8月22日木曜日

32

対象の処理MH

3213年8月22日木曜日

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

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

33

3313年8月22日木曜日

34

対象の処理MH

別の処理

新しいMH

3413年8月22日木曜日

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

35

3513年8月22日木曜日

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

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

36

3613年8月22日木曜日

それがCallSite

37

3713年8月22日木曜日

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

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

38

3813年8月22日木曜日

39

対象の処理MH

CallSite

3913年8月22日木曜日

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

呼び出す

40

4013年8月22日木曜日

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

41

4113年8月22日木曜日

それがbootstrapメソッド

42

4213年8月22日木曜日

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

43

4313年8月22日木曜日

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

呼び出される仕組み

44

4413年8月22日木曜日

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

返し…

45

4513年8月22日木曜日

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

関連づけられる

46

4613年8月22日木曜日

47

対象の処理MH

CallSite

bootstrap 生成

invokedynamic初回実行時に呼び出し

MHを保持する

関連づく

4713年8月22日木曜日

用語のまとめ

48

命令 説明

bootstrapメソッド

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

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

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

4813年8月22日木曜日

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

49

4913年8月22日木曜日

java.lang.invokeパッケージ

50

5013年8月22日木曜日

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

51

5113年8月22日木曜日

52

Lookup lookup = MethodHandles.lookup();

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

MHの生成

5213年8月22日木曜日

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

53

メソッド 説明

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

MHを返す

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

MHを返す

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

MHを返す

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

5313年8月22日木曜日

CallSiteを生成するには…

54

5413年8月22日木曜日

55

CallSite cs = new ConstantCallSite(methodHandle);

CallSiteの生成

5513年8月22日木曜日

CallSiteの具象クラス

56

クラス 説明

ConstantCallSite MHを変更できない

MutableCallSite MHを変更できる

VolatileCallSiteMHを変更でき、

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

5613年8月22日木曜日

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

CallSiteを生成すればよい

57

5713年8月22日木曜日

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

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

58

5813年8月22日木曜日

Java 8からJavaでもindyが

使われるようになった!

59

5913年8月22日木曜日

ラムダ式

60

6013年8月22日木曜日

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

けど…

61

6113年8月22日木曜日

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

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

62

6213年8月22日木曜日

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

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

63

6313年8月22日木曜日

サンプル実行

64

6413年8月22日木曜日

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

65

6513年8月22日木曜日

66

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

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

6613年8月22日木曜日

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

ようにする67

6713年8月22日木曜日

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

便利な機能

68

6813年8月22日木曜日

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

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

69

6913年8月22日木曜日

70

Java 7 invokedynamic の概要

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

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

7013年8月22日木曜日

ご清聴ありがとう

ございました!

71

7113年8月22日木曜日

72

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

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

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

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

7213年8月22日木曜日