250 likes | 355 Views
適用するメソッドを切り替えること で破壊的 クラス拡張で生じるメソッド衝突を 避けられるモジュール機構 Method Shells. 48-126624 竹下若菜 東京大学 創造情報学専攻 千葉研究室. アプリケーションやソフトウェア. l 1 : HTML renderer. 既存のライブラリやフレームワークを組み合わせて実装 既存のプログラムを少し書き換える より多くのコードを再利用できる. l 2 : web browser. l 3 : HTML viewer. Application. 変更のモジュール化. l 1 : HTML renderer.
E N D
適用するメソッドを切り替えることで破壊的クラス拡張で生じるメソッド衝突を避けられるモジュール機構Method Shells 48-126624 竹下若菜 東京大学創造情報学専攻 千葉研究室
アプリケーションやソフトウェア l1: HTML renderer • 既存のライブラリやフレームワークを組み合わせて実装 • 既存のプログラムを少し書き換える • より多くのコードを再利用できる l2: web browser l3: HTML viewer Application
変更のモジュール化 l1: HTML renderer original file 既存コード • 別ファイルに差分のみを記述することでメソッドの追加・再定義できる機能 • 変更をモジュール化できる 再定義 & 追加 • Ruby’s openclass • AspectJ’s aspect • [‘01 Kiczales et al.] • GluonJ • [’10 Chiba et al.] • Classboxes • [’10 Bergel et al.] • etc… l2: web browser another file この機能を 破壊的クラス拡張 と総称する 差分
破壊的クラス拡張 l1: HTML renderer original file class Webpage{ void print(String str){ // standard output • 別ファイルに差分のみを記述することでメソッドの追加・再定義できる機能 • 変更をモジュール化できる void setPopupItem(Popup p, HTML text){ // set text } void popup(HTML text){ Popup p = new Popup(); setPopupItem(p, text); … } 再定義 l2: web browser 追加 another file reviseWebpage{ void print(String str){ // standard output void setPopupItem(Popup p, HTML text){ alert(“disabled”); } void onClick(){ URL url = m.getURL(); popup(url); } GluonJによるコード例
void popup(HTML text){ setPopupItem(p, text); void setPopupItem (Popup p, HTML text){ // show a popup window } 変更の衝突 l1: HTML renderer void setPopupItem (Popup p, HTML text){ } void setPopupItem (Popup p, HTML text){ alert(“disabled”); } どのsetPopupItem メソッドが 有効になるか 分からない l2: web browser l3: HTML viewer void check() { popup(…); …} Application
void popup(HTML text){ setPopupItem(p, text); void setPopupItem (Popup p, HTML text){ // show a popup window } 提案:有効にするメソッドの切り替え l1: HTML renderer void setPopupItem (Popup p, HTML text){ } void setPopupItem (Popup p, HTML text){ alert(“disabled”); } l2: web browser l3: HTML viewer void check() { popup(…); …} Application Application
モジュール機構:Method Shells • モジュール:methodshell • 破壊的クラス拡張とクラス宣言を含む • 有効にするメソッドを切り替えられる • shellグループ • 一度に有効にするメソッドの集合 • include宣言によって定義 • shellグループの切り替え • link宣言によって定義 renderermethodshell methodshellrenderer; class Webpage{ } void setPopupItem(Popup p, HTML text){ // set text } void popup(HTML text){ Popup p = new Popup(); setPopupItem(p, text); … }
モジュール機構:Method Shells • モジュール:methodshell • 破壊的クラス拡張とクラス宣言を含む • 有効にするメソッドを切り替えられる • shellグループ • 一度に有効にするメソッドの集合 • include宣言によって定義 • shellグループの切り替え • link宣言によって定義 renderer viewer browser include 宣言 link 宣言 shell グループ
shellグループの定義・拡張 renderermethodshell methodshellrenderer; class Webpage{ } void setPopupItem(Popup p, HTML text){ // set text} • include宣言でshellグループを定義・拡張できる • 一度に有効になる • includeしたmethodshell中のメソッドは再定義できる void popup(HTML text){ Popup p = new Popup(); setPopupItem(p, text); … } 再定義 browsermethodshell methodshellbrowser; include renderer; revise Webpage{ } void setPopupItem(Popup p, HTML text){ alert(“disabled”);} void onClick(){ URL url = m.getURL(); popup(url);} include 宣言 link 宣言 shell グループ
shellグループの切り替え viewermethodshell viewermethodshell methodshellviewer; include renderer; revise Webpage{ } methodshellrenderer; include renderer; revise Webpage{ } • link宣言で切り替え先のshellグループを指定する • link宣言しているshellグループ内のメソッドを呼び出すと、shellグループが切り替わる void setPopupItem(Popup p, HTML text){ // set text} void setPopupItem(Popup p, HTML text){ // set text} void check(){ popup(…); …} void check(File f){ popup(…); …} applicationmethodshell methodshellapplication; link viewer; } checkメソッドが呼ばれると、切り替わる void main(){ Webpage w = new WebPage(); w.check(); w.onClick();} include 宣言 link 宣言 shell グループ
void popup(HTML text){ setPopupItem(p, text); } void setPopupItem (Popup p, HTML text){ // show a popup window } 全体図 renderer void setPopupItem (Popup p, HTML text){ alert(“disabled”); } void onClick(){ popup(getURL()); } void setPopupItem (Popup p, HTML text){ //show bold and red text } browser viewer voidmain(){ w.onClick(); w.check(); } void check() { popup(…); …} include 宣言 Application application link 宣言 shell グループ
void popup(HTML text){ setPopupItem(p, text); } void setPopupItem (Popup p, HTML text){ // show a popup window } 全体図 renderer void setPopupItem (Popup p, HTML text){ alert(“disabled”); } void onClick(){ popup(getURL()); } void setPopupItem (Popup p, HTML text){ //show bold and red text } browser viewer voidmain(){ w.onClick(); w.check(); } void check() { popup(…); …} include 宣言 Application application link 宣言 shell グループ
void popup(HTML text){ setPopupItem(p, text); } void setPopupItem (Popup p, HTML text){ // show a popup window } 全体図 renderer void setPopupItem (Popup p, HTML text){ alert(“disabled”); } void onClick(){ popup(getURL()); } void setPopupItem (Popup p, HTML text){ //show bold and red text } browser viewer voidmain(){ w.onClick(); w.check(); } void check() { popup(…); …} include 宣言 Application application link 宣言 shell グループ
メソッド探索 5 2 renderer • linkしているshellグループを探索 • 現在有効なグループを探索 • グローバルなグループを探索 4 1 browser viewer 3 Application application メソッド 呼び出し include 宣言 link 宣言 shell グループ
最適化手法の提案 • 実行時間を減らす • コンパイル時にメソッド名を変更 • メソッド名とメソッドが一対一に対応 • 分割コンパイルをあきらめている 呼び出していることがコンパイル時に判明 applicationmethodshell browsermethodshell revise Webpage{ } void main(){ Webpage w = new WebPage(); w.onClick();} void onClick(){ URL url = m.getURL(); popup(url);} コンパイル時に変更 void main(){ Webpage w = new WebPage(); w.onClick_browser();} void onClick_browser(){ URL url = m.getURL(); popup(url);}
実験 • 最適化版のプロトタイプコンパイラを実装 • 最適化手法の効果を測定 • セマンティクスに沿った実装と最適化手法とを比較 • methodshell数増加に伴うメソッド探索時間の増加を測定 • セマンティクスに沿った実装:手動でコンパイル。実行時処理の部分のみReflectionAPIを用いて実装。 • GluonJ、オリジナルのJavaと最適化手法とを比較 • include宣言の影響を測定 • 破壊的クラス拡張の影響を測定 実験環境 CentOS release 6.2 Intel® Xeon® CPU E5-2687W 3.10GHz メモリ64GB OpenJDK 1.7.0
n個 (d1) root n 個 (a1) root (a2) (a) includeの深さが増えていくもの (d2) (d) linkの幅が増えていくもの (b1) (e) n 個 root (e’) root (b2) (b) includeの幅が増えていくもの n個 (e) あるmethodshellが所属しているshellグループの数が増えていくもの ((e)のメソッド中で(e’)のメソッドを呼び出している) n個 (c) root s1が”include s2”をしている s2 s1 (c) linkの深さが増えていくもの s1が”link s2”をしている s2 s1
実験 • 最適化版のプロトタイプコンパイラを実装 • 最適化手法の効果を測定 • セマンティクスに沿った実装と最適化手法とを比較 • methodshell数増加に伴うメソッド探索時間の増加を測定 • セマンティクスに沿った実装:手動でコンパイル。実行時処理の部分のみReflectionAPIを用いて実装。 • GluonJ、オリジナルのJavaと最適化手法とを比較 • include宣言の影響を測定 • 破壊的クラス拡張の影響を測定 実験環境 CentOS release 6.2 Intel® Xeon® CPU E5-2687W 3.10GHz メモリ64GB OpenJDK 1.7.0
関連研究 • 破壊的クラス拡張のスコープを制限 • Classbox[’05 Alexandre, et al.] • Rubyのrefinement • NewSpeak[‘10 Bracha, et al.] • 有効なメソッドの切り替えはできない • 有効な破壊的クラス拡張の実行時切り替え • Us[’96 Smith, et al.] • Context-oriented Programming[’08 Hirschfeld, et al.] • Method Shellsの方がより宣言的
発表 • 第14回プログラミングおよびプログラミング言語ワークショップ • 2012/3/8~10 ポスター発表 • 日本ソフトウェア科学会第29回大会 • 2012/8/22~24 論文および登壇発表 • 第15回プログラミングおよびプログラミング言語ワークショップ • 2013/3/4~6 ポスター発表 • ACM Student Research Competition • 2013/3/25~27 final roundまで進出(ポスター発表と登壇発表) • International Conference on Software Composition 2013 • 2013/6/19 論文および登壇発表 • 第97回プログラミング研究会 • 2014/1/14~15 登壇発表、論文誌査読待ち
まとめ • 破壊的クラス拡張 • 既存のコードを書き換えずに差分のみの記述でメソッドの追加・再定義ができる機能 • メソッドの衝突の危険がある • Method Shells • 有効な破壊的クラス拡張を切り替えることができるモジュール機構 • 一度に適用したい破壊的クラス拡張をshellグループにまとめることができる • 最適化手法を提案し、効果を測定した